@@ -43,20 +43,20 @@ class ToplevelBuilder implements OutputFactory.Builder {
43
43
private static final int DECLS_PER_HEADER_CLASS = Integer .getInteger ("jextract.decls.per.header" , 1000 );
44
44
45
45
private int declCount ;
46
- private final List <SourceFileBuilder > builders = new ArrayList <>();
47
- private final HeaderFileBuilder firstHeader ;
46
+ private final List <SourceFileBuilder > headerBuilders = new ArrayList <>();
47
+ private final List < SourceFileBuilder > otherBuilders = new ArrayList <>() ;
48
48
private HeaderFileBuilder lastHeader ;
49
- private int headersCount ;
50
49
private final ClassDesc headerDesc ;
51
50
52
51
ToplevelBuilder (String packageName , String headerClassName , List <String > libraries ) {
53
52
this .headerDesc = ClassDesc .of (packageName , headerClassName );
54
53
SourceFileBuilder sfb = SourceFileBuilder .newSourceFile (packageName , headerClassName );
55
- lastHeader = firstHeader = createFirstHeader (sfb , libraries );
54
+ headerBuilders .add (sfb );
55
+ lastHeader = createFirstHeader (sfb , libraries );
56
56
}
57
57
58
58
private static HeaderFileBuilder createFirstHeader (SourceFileBuilder sfb , List <String > libraries ) {
59
- HeaderFileBuilder first = new HeaderFileBuilder (sfb , sfb .className (), "#{SUPER}" , sfb .className ());
59
+ HeaderFileBuilder first = new HeaderFileBuilder (sfb , STR . "\{ sfb .className ()}#{SUFFIX}" , null , sfb .className ());
60
60
first .classBegin ();
61
61
first .emitFirstHeaderPreamble (libraries );
62
62
// emit basic primitive types
@@ -77,24 +77,42 @@ private static HeaderFileBuilder createFirstHeader(SourceFileBuilder sfb, List<S
77
77
} else {
78
78
first .appendIndentedLines ("public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG;" );
79
79
}
80
+ first .emitRuntimeHelperMethods ();
80
81
return first ;
81
82
}
82
83
83
84
public List <JavaFileObject > toFiles () {
84
- boolean hasOneHeader = lastHeader == firstHeader ;
85
- if (hasOneHeader ) {
86
- firstHeader .emitRuntimeHelperMethods ();
87
- }
88
85
lastHeader .classEnd ();
89
86
90
87
List <JavaFileObject > files = new ArrayList <>();
91
- files .add (firstHeader .sourceFileBuilder ().toFile (s -> s .replace ("extends #{SUPER}" ,
92
- hasOneHeader ? "" : "extends " + lastHeader .className ())));
93
- files .addAll (builders .stream ()
88
+
89
+ if (headerBuilders .size () == 1 ) {
90
+ files .add (headerBuilders .get (0 ).toFile (s -> s .replace ("#{SUFFIX}" , "" )));
91
+ } else {
92
+ // adjust suffixes so that the last header class becomes the main header class,
93
+ // and extends all the other header classes
94
+ int suffix = headerBuilders .size () - 1 ;
95
+ for (SourceFileBuilder header : headerBuilders ) {
96
+ String currentSuffix = suffix == 0 ?
97
+ "" : // main header class, drop the suffix
98
+ STR ."_\{suffix }" ;
99
+ String prevSuffix = STR ."_\{suffix + 1 }" ;
100
+ files .add (header .toFile (currentSuffix ,
101
+ s -> s .replace ("#{SUFFIX}" , currentSuffix )
102
+ .replace ("#{PREV_SUFFIX}" , prevSuffix )));
103
+ suffix --;
104
+ }
105
+ }
106
+ // add remaining builders
107
+ files .addAll (otherBuilders .stream ()
94
108
.map (SourceFileBuilder ::toFile ).toList ());
95
109
return files ;
96
110
}
97
111
112
+ public String mainHeaderClassName () {
113
+ return headerDesc .displayName ();
114
+ }
115
+
98
116
public String packageName () {
99
117
return headerDesc .packageName ();
100
118
}
@@ -125,41 +143,37 @@ public void addTypedef(Declaration.Typedef typedefTree, String superClass, Type
125
143
nextHeader ().emitPointerTypedef (typedefTree , javaName );
126
144
} else {
127
145
SourceFileBuilder sfb = SourceFileBuilder .newSourceFile (packageName (), javaName );
128
- TypedefBuilder .generate (sfb , sfb .className (), superClass , firstHeader . className (), typedefTree );
129
- builders .add (sfb );
146
+ TypedefBuilder .generate (sfb , sfb .className (), superClass , mainHeaderClassName (), typedefTree );
147
+ otherBuilders .add (sfb );
130
148
}
131
149
}
132
150
133
151
@ Override
134
152
public StructBuilder addStruct (Declaration .Scoped tree ) {
135
153
SourceFileBuilder sfb = SourceFileBuilder .newSourceFile (packageName (), JavaName .getOrThrow (tree ));
136
- builders .add (sfb );
137
- StructBuilder structBuilder = new StructBuilder (sfb , "public" , sfb .className (), null , firstHeader . className (), tree );
154
+ otherBuilders .add (sfb );
155
+ StructBuilder structBuilder = new StructBuilder (sfb , "public" , sfb .className (), null , mainHeaderClassName (), tree );
138
156
structBuilder .begin ();
139
157
return structBuilder ;
140
158
}
141
159
142
160
@ Override
143
161
public void addFunctionalInterface (String name , Type .Function funcType ) {
144
162
SourceFileBuilder sfb = SourceFileBuilder .newSourceFile (packageName (), name );
145
- builders .add (sfb );
146
- FunctionalInterfaceBuilder .generate (sfb , sfb .className (), null , firstHeader . className (), funcType ,
163
+ otherBuilders .add (sfb );
164
+ FunctionalInterfaceBuilder .generate (sfb , sfb .className (), null , mainHeaderClassName (), funcType ,
147
165
funcType .parameterNames ().map (NameMangler ::javaSafeIdentifiers ));
148
166
}
149
167
150
168
private HeaderFileBuilder nextHeader () {
151
169
if (declCount == DECLS_PER_HEADER_CLASS ) {
152
- boolean wasFirstHeader = lastHeader == firstHeader ;
153
- if (wasFirstHeader ) {
154
- firstHeader .emitRuntimeHelperMethods ();
155
- }
156
- String className = headerDesc .displayName () + "_" + ++headersCount ;
157
- SourceFileBuilder sfb = SourceFileBuilder .newSourceFile (packageName (), className );
158
- HeaderFileBuilder headerFileBuilder = new HeaderFileBuilder (sfb , sfb .className (),
159
- wasFirstHeader ? null : lastHeader .className (), firstHeader .className ());
170
+ SourceFileBuilder sfb = SourceFileBuilder .newSourceFile (packageName (), mainHeaderClassName ());
171
+ String className = mainHeaderClassName () + "#{SUFFIX}" ;
172
+ HeaderFileBuilder headerFileBuilder = new HeaderFileBuilder (sfb , className ,
173
+ mainHeaderClassName () + "#{PREV_SUFFIX}" , mainHeaderClassName ());
160
174
lastHeader .classEnd ();
161
175
headerFileBuilder .classBegin ();
162
- builders .add (sfb );
176
+ headerBuilders .add (sfb );
163
177
lastHeader = headerFileBuilder ;
164
178
declCount = 1 ;
165
179
return headerFileBuilder ;
0 commit comments