37
37
import jdk .javadoc .internal .doclets .toolkit .util .Utils ;
38
38
39
39
import javax .lang .model .element .Element ;
40
+ import javax .lang .model .element .ElementKind ;
40
41
import javax .lang .model .element .Modifier ;
41
42
import javax .lang .model .element .ModuleElement ;
42
43
import javax .lang .model .element .PackageElement ;
43
44
import javax .lang .model .element .RecordComponentElement ;
44
45
import javax .lang .model .element .TypeElement ;
45
46
import javax .lang .model .type .TypeMirror ;
47
+ import javax .lang .model .util .ElementKindVisitor14 ;
48
+ import java .util .ArrayList ;
49
+ import java .util .Collections ;
46
50
import java .util .List ;
47
51
import java .util .Set ;
52
+ import java .util .SortedSet ;
48
53
import java .util .TreeSet ;
49
54
import java .util .stream .Collectors ;
50
55
51
56
import static javax .lang .model .element .Modifier .ABSTRACT ;
57
+ import static javax .lang .model .element .Modifier .FINAL ;
52
58
import static javax .lang .model .element .Modifier .NATIVE ;
59
+ import static javax .lang .model .element .Modifier .PRIVATE ;
60
+ import static javax .lang .model .element .Modifier .PROTECTED ;
53
61
import static javax .lang .model .element .Modifier .PUBLIC ;
62
+ import static javax .lang .model .element .Modifier .STATIC ;
54
63
import static javax .lang .model .element .Modifier .STRICTFP ;
55
64
import static javax .lang .model .element .Modifier .SYNCHRONIZED ;
56
65
@@ -92,17 +101,20 @@ public static Content getPackageSignature(PackageElement pkg, PackageWriterImpl
92
101
static class TypeSignature {
93
102
94
103
private final TypeElement typeElement ;
95
- private final ClassWriterImpl classWriter ;
104
+ private final HtmlDocletWriter writer ;
96
105
private final Utils utils ;
97
106
private final HtmlConfiguration configuration ;
98
107
private Content modifiers ;
99
108
100
- TypeSignature (TypeElement typeElement , ClassWriterImpl classWriter ) {
101
- this .typeElement = typeElement ;
102
- this .classWriter = classWriter ;
103
- this .utils = classWriter .utils ;
104
- this .configuration = classWriter .configuration ;
105
- }
109
+ private static final Set <String > previewModifiers = Collections .emptySet ();
110
+
111
+ TypeSignature (TypeElement typeElement , HtmlDocletWriter writer ) {
112
+ this .typeElement = typeElement ;
113
+ this .writer = writer ;
114
+ this .utils = writer .utils ;
115
+ this .configuration = writer .configuration ;
116
+ this .modifiers = markPreviewModifiers (getModifiers ());
117
+ }
106
118
107
119
public TypeSignature setModifiers (Content modifiers ) {
108
120
this .modifiers = modifiers ;
@@ -111,24 +123,24 @@ public TypeSignature setModifiers(Content modifiers) {
111
123
112
124
public Content toContent () {
113
125
Content content = new ContentBuilder ();
114
- Content annotationInfo = classWriter .getAnnotationInfo (typeElement , true );
126
+ Content annotationInfo = writer .getAnnotationInfo (typeElement , true );
115
127
if (!annotationInfo .isEmpty ()) {
116
128
content .add (HtmlTree .SPAN (HtmlStyle .annotations , annotationInfo ));
117
129
}
118
130
content .add (HtmlTree .SPAN (HtmlStyle .modifiers , modifiers ));
119
131
120
132
HtmlTree nameSpan = new HtmlTree (TagName .SPAN ).setStyle (HtmlStyle .elementName );
121
133
Content className = Text .of (utils .getSimpleName (typeElement ));
122
- if (classWriter . options .linkSource ()) {
123
- classWriter .addSrcLink (typeElement , className , nameSpan );
134
+ if (configuration . getOptions () .linkSource ()) {
135
+ writer .addSrcLink (typeElement , className , nameSpan );
124
136
} else {
125
137
nameSpan .addStyle (HtmlStyle .typeNameLabel ).add (className );
126
138
}
127
139
HtmlLinkInfo linkInfo = new HtmlLinkInfo (configuration ,
128
140
HtmlLinkInfo .Kind .CLASS_SIGNATURE , typeElement );
129
141
//Let's not link to ourselves in the signature.
130
142
linkInfo .linkToSelf = false ;
131
- nameSpan .add (classWriter .getTypeParameterLinks (linkInfo ));
143
+ nameSpan .add (writer .getTypeParameterLinks (linkInfo ));
132
144
content .add (nameSpan );
133
145
134
146
if (utils .isRecord (typeElement )) {
@@ -142,7 +154,7 @@ public Content toContent() {
142
154
if (superclass != null ) {
143
155
content .add (DocletConstants .NL );
144
156
extendsImplements .add ("extends " );
145
- Content link = classWriter .getLink (new HtmlLinkInfo (configuration ,
157
+ Content link = writer .getLink (new HtmlLinkInfo (configuration ,
146
158
HtmlLinkInfo .Kind .CLASS_SIGNATURE_PARENT_NAME ,
147
159
superclass ));
148
160
extendsImplements .add (link );
@@ -163,7 +175,7 @@ public Content toContent() {
163
175
} else {
164
176
extendsImplements .add (", " );
165
177
}
166
- Content link = classWriter .getLink (new HtmlLinkInfo (configuration ,
178
+ Content link = writer .getLink (new HtmlLinkInfo (configuration ,
167
179
HtmlLinkInfo .Kind .CLASS_SIGNATURE_PARENT_NAME ,
168
180
type ));
169
181
extendsImplements .add (link );
@@ -189,13 +201,13 @@ public Content toContent() {
189
201
} else {
190
202
permitsSpan .add (", " );
191
203
}
192
- Content link = classWriter .getLink (new HtmlLinkInfo (configuration ,
204
+ Content link = writer .getLink (new HtmlLinkInfo (configuration ,
193
205
HtmlLinkInfo .Kind .PERMITTED_SUBCLASSES ,
194
206
type ));
195
207
permitsSpan .add (link );
196
208
}
197
209
if (linkablePermits .size () < permits .size ()) {
198
- Content c = Text .of (classWriter . resources .getText ("doclet.not.exhaustive" ));
210
+ Content c = Text .of (configuration . getDocResources () .getText ("doclet.not.exhaustive" ));
199
211
permitsSpan .add (" " );
200
212
permitsSpan .add (HtmlTree .SPAN (HtmlStyle .permitsNote , c ));
201
213
}
@@ -210,9 +222,9 @@ private Content getRecordComponents() {
210
222
String sep = "" ;
211
223
for (RecordComponentElement e : typeElement .getRecordComponents ()) {
212
224
content .add (sep );
213
- classWriter .getAnnotations (e .getAnnotationMirrors (), false )
225
+ writer .getAnnotations (e .getAnnotationMirrors (), false )
214
226
.forEach (a -> { content .add (a ).add (" " ); });
215
- Content link = classWriter .getLink (new HtmlLinkInfo (configuration , HtmlLinkInfo .Kind .RECORD_COMPONENT ,
227
+ Content link = writer .getLink (new HtmlLinkInfo (configuration , HtmlLinkInfo .Kind .RECORD_COMPONENT ,
216
228
e .asType ()));
217
229
content .add (link );
218
230
content .add (Entity .NO_BREAK_SPACE );
@@ -222,6 +234,112 @@ private Content getRecordComponents() {
222
234
content .add (")" );
223
235
return content ;
224
236
}
237
+
238
+ private Content markPreviewModifiers (List <String > modifiers ) {
239
+ Content content = new ContentBuilder ();
240
+ String sep = null ;
241
+ for (String modifier : modifiers ) {
242
+ if (sep != null ) {
243
+ content .add (sep );
244
+ }
245
+ content .add (modifier );
246
+ if (previewModifiers .contains (modifier )) {
247
+ content .add (HtmlTree .SUP (writer .links .createLink (
248
+ configuration .htmlIds .forPreviewSection (typeElement ),
249
+ configuration .contents .previewMark )));
250
+ }
251
+ sep = " " ;
252
+ }
253
+ content .add (" " );
254
+ return content ;
255
+ }
256
+
257
+ private List <String > getModifiers () {
258
+ SortedSet <Modifier > modifiers = new TreeSet <>(typeElement .getModifiers ());
259
+ modifiers .remove (NATIVE );
260
+ modifiers .remove (STRICTFP );
261
+ modifiers .remove (SYNCHRONIZED );
262
+
263
+ return new ElementKindVisitor14 <List <String >, SortedSet <Modifier >>() {
264
+ final List <String > list = new ArrayList <>();
265
+
266
+ void addVisibilityModifier (Set <Modifier > modifiers ) {
267
+ if (modifiers .contains (PUBLIC )) {
268
+ list .add ("public" );
269
+ } else if (modifiers .contains (PROTECTED )) {
270
+ list .add ("protected" );
271
+ } else if (modifiers .contains (PRIVATE )) {
272
+ list .add ("private" );
273
+ }
274
+ }
275
+
276
+ void addStatic (Set <Modifier > modifiers ) {
277
+ if (modifiers .contains (STATIC )) {
278
+ list .add ("static" );
279
+ }
280
+ }
281
+
282
+ void addSealed (TypeElement e ) {
283
+ if (e .getModifiers ().contains (Modifier .SEALED )) {
284
+ list .add ("sealed" );
285
+ } else if (e .getModifiers ().contains (Modifier .NON_SEALED )) {
286
+ list .add ("non-sealed" );
287
+ }
288
+ }
289
+
290
+ void addModifiers (Set <Modifier > modifiers ) {
291
+ modifiers .stream ()
292
+ .map (Modifier ::toString )
293
+ .forEachOrdered (list ::add );
294
+ }
295
+
296
+ @ Override
297
+ public List <String > visitTypeAsInterface (TypeElement e , SortedSet <Modifier > mods ) {
298
+ addVisibilityModifier (mods );
299
+ addStatic (mods );
300
+ addSealed (e );
301
+ list .add ("interface" );
302
+ return list ;
303
+ }
304
+
305
+ @ Override
306
+ public List <String > visitTypeAsEnum (TypeElement e , SortedSet <Modifier > mods ) {
307
+ addVisibilityModifier (mods );
308
+ addStatic (mods );
309
+ list .add ("enum" );
310
+ return list ;
311
+ }
312
+
313
+ @ Override
314
+ public List <String > visitTypeAsAnnotationType (TypeElement e , SortedSet <Modifier > mods ) {
315
+ addVisibilityModifier (mods );
316
+ addStatic (mods );
317
+ list .add ("@interface" );
318
+ return list ;
319
+ }
320
+
321
+ @ Override
322
+ public List <String > visitTypeAsRecord (TypeElement e , SortedSet <Modifier > mods ) {
323
+ mods .remove (FINAL ); // suppress the implicit `final`
324
+ return visitTypeAsClass (e , mods );
325
+ }
326
+
327
+ @ Override
328
+ public List <String > visitTypeAsClass (TypeElement e , SortedSet <Modifier > mods ) {
329
+ addModifiers (mods );
330
+ String keyword = e .getKind () == ElementKind .RECORD ? "record" : "class" ;
331
+ list .add (keyword );
332
+ return list ;
333
+ }
334
+
335
+ @ Override
336
+ protected List <String > defaultAction (Element e , SortedSet <Modifier > mods ) {
337
+ addModifiers (mods );
338
+ return list ;
339
+ }
340
+
341
+ }.visit (typeElement , modifiers );
342
+ }
225
343
}
226
344
227
345
/**
0 commit comments