@@ -30,8 +30,23 @@ namespace Java.Interop.Bindings.Compiler
30
30
{
31
31
public class DefaultOutputPathProvider : OutputPathProvider
32
32
{
33
- public DefaultOutputPathProvider ( GeneratorContext context ) : base ( context )
34
- { }
33
+ public OutputTreeLayout TreeLayout { get ; }
34
+
35
+ public DefaultOutputPathProvider ( GeneratorContext context , OutputTreeLayout treeLayout ) : base ( context )
36
+ {
37
+ TreeLayout = treeLayout ?? throw new ArgumentNullException ( nameof ( treeLayout ) ) ;
38
+ }
39
+
40
+ public override void Validate ( )
41
+ {
42
+ switch ( TreeLayout . NestedTypesStyle ) {
43
+ case OutputNestedTypesStyle . SeparateFileDot :
44
+ case OutputNestedTypesStyle . SeparateFileUnderscore :
45
+ if ( ! Context . UsePartialClasses )
46
+ throw new InvalidOperationException ( "Nested types in separate files require partial classes" ) ;
47
+ break ;
48
+ }
49
+ }
35
50
36
51
public override FilesystemPath GetPathFor ( string rootDirectory , HierarchyElement element )
37
52
{
@@ -41,47 +56,149 @@ public override FilesystemPath GetPathFor (string rootDirectory, HierarchyElemen
41
56
if ( element == null )
42
57
throw new ArgumentNullException ( nameof ( element ) ) ;
43
58
44
- FilesystemPath relativePath = null ;
45
59
switch ( element ) {
46
60
case HierarchyNamespace ns :
47
- relativePath = new FilesystemPath ( MakePath ( ns . GetManagedName ( true ) ) , true ) ;
61
+ case HierarchyClass klass :
62
+ case HierarchyInterface iface :
63
+ case HierarchyEnum enm :
48
64
break ;
49
65
50
- case HierarchyClass klass :
51
- relativePath = GetFilePath ( klass ) ;
66
+ default :
67
+ throw new InvalidOperationException ( $ "Unsupported hierarchy type '{ element . GetType ( ) } '") ;
68
+ }
69
+
70
+ Func < string , HierarchyElement , FilesystemPath > getter = null ;
71
+ switch ( TreeLayout . NamespaceTreeStyle ) {
72
+ case OutputNamespaceTreeStyle . Single :
73
+ getter = GetPathFor_Single ;
52
74
break ;
53
75
54
- case HierarchyInterface iface :
55
- relativePath = GetFilePath ( iface ) ;
76
+ case OutputNamespaceTreeStyle . Shallow :
77
+ getter = GetPathFor_Shallow ;
56
78
break ;
57
79
58
- case HierarchyEnum enm :
59
- relativePath = GetFilePath ( enm ) ;
80
+ case OutputNamespaceTreeStyle . Deep :
81
+ getter = GetPathFor_Deep ;
82
+ break ;
83
+
84
+ case OutputNamespaceTreeStyle . FirstLevelThenFullShallow :
85
+ getter = GetPathFor_FirstLevelThenFullShallow ;
86
+ break ;
87
+
88
+ case OutputNamespaceTreeStyle . FirstLevelThenFullSingle :
89
+ getter = GetPathFor_FirstLevelThenFullSingle ;
90
+ break ;
91
+
92
+ case OutputNamespaceTreeStyle . FirstLevelThenShortShallow :
93
+ getter = GetPathFor_FirstLevelThenShortShallow ;
94
+ break ;
95
+
96
+ case OutputNamespaceTreeStyle . FirstLevelThenShortSingle :
97
+ getter = GetPathFor_FirstLevelThenShortSingle ;
60
98
break ;
61
99
62
100
default :
63
- throw new InvalidOperationException ( $ "Unsupported hierarchy type ' { element . GetType ( ) } ' ") ;
101
+ throw new InvalidOperationException ( $ "Unsupported namespace tree style { TreeLayout . NamespaceTreeStyle } ") ;
64
102
}
65
103
66
- return relativePath ;
104
+ return getter ( rootDirectory , element ) ;
105
+ }
67
106
68
- string MakePath ( string elementName , string extension = null )
69
- {
70
- string relPath = elementName ? . Replace ( '.' , Path . DirectorySeparatorChar ) ;
71
- if ( relPath == null )
72
- return null ;
107
+ protected FilesystemPath GetPathFor_Single ( string rootDirectory , HierarchyElement element )
108
+ {
109
+ if ( element is HierarchyNamespace )
110
+ return null ;
73
111
74
- string ret = Path . Combine ( rootDirectory , relPath ) ;
75
- if ( ! String . IsNullOrEmpty ( extension ) )
76
- ret += $ ".{ extension } ";
112
+ throw new NotImplementedException ( ) ;
113
+ }
77
114
78
- return ret ;
79
- }
115
+ protected FilesystemPath GetPathFor_Shallow ( string rootDirectory , HierarchyElement element )
116
+ {
117
+ throw new NotImplementedException ( ) ;
118
+ }
80
119
81
- FilesystemPath GetFilePath ( HierarchyElement e )
82
- {
83
- return new FilesystemPath ( MakePath ( e . GetManagedName ( true ) , Context . CodeGenerator . FileExtension ) , false ) ;
120
+ protected FilesystemPath GetPathFor_Deep ( string rootDirectory , HierarchyElement element )
121
+ {
122
+ throw new NotImplementedException ( ) ;
123
+ }
124
+
125
+ protected FilesystemPath GetPathFor_FirstLevelThenFullShallow ( string rootDirectory , HierarchyElement element )
126
+ {
127
+ string fullManagedName = element . GetManagedName ( true ) ;
128
+ bool isDirectory ;
129
+ string path = GetFirstNameSegment ( fullManagedName ) ;
130
+
131
+ Logger . Debug ( $ "Element: { element . FullName } (managed: { fullManagedName } )") ;
132
+ Logger . Debug ( $ "Initial path: { path } ") ;
133
+ if ( element is HierarchyNamespace ) {
134
+ Logger . Debug ( "Is namespace" ) ;
135
+ isDirectory = true ;
136
+ path = Path . Combine ( path , fullManagedName ) ;
137
+ } else {
138
+ var obj = element as HierarchyObject ;
139
+ if ( obj == null )
140
+ throw new InvalidOperationException ( "Only HierarchyObject and HierarchyNamespace instances can be used to compute output file name" ) ;
141
+ Logger . Debug ( "Is type" ) ;
142
+ isDirectory = false ;
143
+ path = Path . Combine ( path , obj . GetNamespace ( ) , obj . GetNameWithoutNamespace ( ) ) ;
84
144
}
145
+ Logger . Debug ( $ "Final relative path: { path } ") ;
146
+ Logger . Debug ( String . Empty ) ;
147
+ return GetFilePath ( rootDirectory , path , isDirectory ) ;
148
+ }
149
+
150
+ protected FilesystemPath GetPathFor_FirstLevelThenShortShallow ( string rootDirectory , HierarchyElement element )
151
+ {
152
+ throw new NotImplementedException ( ) ;
153
+ }
154
+
155
+ protected FilesystemPath GetPathFor_FirstLevelThenFullSingle ( string rootDirectory , HierarchyElement element )
156
+ {
157
+ throw new NotImplementedException ( ) ;
158
+ }
159
+
160
+ protected FilesystemPath GetPathFor_FirstLevelThenShortSingle ( string rootDirectory , HierarchyElement element )
161
+ {
162
+ throw new NotImplementedException ( ) ;
163
+ }
164
+
165
+ protected string MakePath ( string rootDirectory , string elementName , string extension = null )
166
+ {
167
+ string ret = Path . Combine ( rootDirectory , elementName ) ;
168
+ if ( ! String . IsNullOrEmpty ( extension ) )
169
+ ret += $ ".{ extension } ";
170
+
171
+ return ret ;
172
+ }
173
+
174
+ protected FilesystemPath GetFilePath ( string rootDirectory , string fileName , bool isDirectory = false )
175
+ {
176
+ return new FilesystemPath ( MakePath ( rootDirectory , fileName , isDirectory ? null : Context . CodeGenerator . FileExtension ) , isDirectory ) ;
177
+ }
178
+
179
+ string GetLastNameSegment ( string fullManagedName )
180
+ {
181
+ return GetNameSegment ( fullManagedName , false ) ;
182
+ }
183
+
184
+ string GetFirstNameSegment ( string fullManagedName )
185
+ {
186
+ return GetNameSegment ( fullManagedName , true ) ;
187
+ }
188
+
189
+ string GetNameSegment ( string fullManagedName , bool first )
190
+ {
191
+ if ( String . IsNullOrEmpty ( fullManagedName ) )
192
+ throw new ArgumentException ( "must not be null or empty" , nameof ( fullManagedName ) ) ;
193
+
194
+ int dot = first ? fullManagedName . IndexOf ( '.' ) : fullManagedName . LastIndexOf ( '.' ) ;
195
+ if ( dot == 0 )
196
+ throw new InvalidOperationException ( $ "Full valid managed type name (including namespace) expected, got '{ fullManagedName } '") ;
197
+
198
+ if ( dot < 0 )
199
+ return fullManagedName ;
200
+
201
+ return first ? fullManagedName . Substring ( 0 , dot ) : fullManagedName . Substring ( dot + 1 ) ;
85
202
}
86
203
}
87
204
}
0 commit comments