103 names = Names.instance(context); |
103 names = Names.instance(context); |
104 log = Log.instance(context); |
104 log = Log.instance(context); |
105 syms = Symtab.instance(context); |
105 syms = Symtab.instance(context); |
106 annotate = Annotate.instance(context); |
106 annotate = Annotate.instance(context); |
107 attr = Attr.instance(context); |
107 attr = Attr.instance(context); |
108 Options options = Options.instance(context); |
|
109 } |
108 } |
110 |
109 |
111 /** |
110 /** |
112 * Separate type annotations from declaration annotations and |
111 * Separate type annotations from declaration annotations and |
113 * determine the correct positions for type annotations. |
112 * determine the correct positions for type annotations. |
114 * This version only visits types in signatures and should be |
113 * This version only visits types in signatures and should be |
115 * called from MemberEnter. |
114 * called from MemberEnter. |
116 * The method takes the Annotate object as parameter and |
|
117 * adds an Annotate.Worker to the correct Annotate queue for |
|
118 * later processing. |
|
119 */ |
115 */ |
120 public void organizeTypeAnnotationsSignatures(final Env<AttrContext> env, final JCClassDecl tree) { |
116 public void organizeTypeAnnotationsSignatures(final Env<AttrContext> env, final JCClassDecl tree) { |
121 annotate.afterRepeated( new Worker() { |
117 annotate.afterTypes(new Runnable() { |
122 @Override |
118 @Override |
123 public void run() { |
119 public void run() { |
124 JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); |
120 JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); |
125 |
121 |
126 try { |
122 try { |
127 new TypeAnnotationPositions(true).scan(tree); |
123 new TypeAnnotationPositions(true).scan(tree); |
128 } finally { |
124 } finally { |
129 log.useSource(oldSource); |
125 log.useSource(oldSource); |
130 } |
126 } |
131 } |
127 } |
132 } ); |
128 }); |
133 } |
129 } |
134 |
130 |
135 public void validateTypeAnnotationsSignatures(final Env<AttrContext> env, final JCClassDecl tree) { |
131 public void validateTypeAnnotationsSignatures(final Env<AttrContext> env, final JCClassDecl tree) { |
136 annotate.validate(new Worker() { //validate annotations |
132 annotate.validate(new Runnable() { //validate annotations |
137 @Override |
133 @Override |
138 public void run() { |
134 public void run() { |
139 JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); |
135 JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); |
140 |
136 |
141 try { |
137 try { |
142 attr.validateTypeAnnotations(tree, true); |
138 attr.validateTypeAnnotations(tree, true); |
143 } finally { |
139 } finally { |
144 log.useSource(oldSource); |
140 log.useSource(oldSource); |
145 } |
141 } |
146 } |
142 } |
147 } ); |
143 }); |
148 } |
144 } |
149 |
145 |
150 /** |
146 /** |
151 * This version only visits types in bodies, that is, field initializers, |
147 * This version only visits types in bodies, that is, field initializers, |
152 * top-level blocks, and method bodies, and should be called from Attr. |
148 * top-level blocks, and method bodies, and should be called from Attr. |
153 */ |
149 */ |
154 public void organizeTypeAnnotationsBodies(JCClassDecl tree) { |
150 public void organizeTypeAnnotationsBodies(JCClassDecl tree) { |
155 new TypeAnnotationPositions(false).scan(tree); |
151 new TypeAnnotationPositions(false).scan(tree); |
156 } |
152 } |
157 |
153 |
158 public enum AnnotationType { DECLARATION, TYPE, BOTH } |
154 public enum AnnotationType { DECLARATION, TYPE, NONE, BOTH } |
|
155 |
|
156 public List<Attribute> annotationTargets(Attribute.Compound anno) { |
|
157 Attribute.Compound atTarget = anno.type.tsym.getAnnotationTypeMetadata().getTarget(); |
|
158 if (atTarget == null) { |
|
159 return null; |
|
160 } |
|
161 |
|
162 Attribute atValue = atTarget.member(names.value); |
|
163 if (!(atValue instanceof Attribute.Array)) { |
|
164 return null; |
|
165 } |
|
166 |
|
167 List<Attribute> targets = ((Array)atValue).getValue(); |
|
168 if (targets.stream().anyMatch(a -> !(a instanceof Attribute.Enum))) { |
|
169 return null; |
|
170 } |
|
171 |
|
172 return targets; |
|
173 } |
159 |
174 |
160 /** |
175 /** |
161 * Determine whether an annotation is a declaration annotation, |
176 * Determine whether an annotation is a declaration annotation, |
162 * a type annotation, or both. |
177 * a type annotation, or both. |
163 */ |
178 */ |
164 public AnnotationType annotationType(Attribute.Compound a, Symbol s) { |
179 public AnnotationType annotationTargetType(Attribute.Compound a, Symbol s) { |
165 Attribute.Compound atTarget = |
180 List<Attribute> targets = annotationTargets(a); |
166 a.type.tsym.attribute(syms.annotationTargetType.tsym); |
181 return (targets == null) ? |
167 if (atTarget == null) { |
182 AnnotationType.DECLARATION : |
168 return inferTargetMetaInfo(a, s); |
183 targets.stream() |
169 } |
184 .map(attr -> targetToAnnotationType(attr, s)) |
170 Attribute atValue = atTarget.member(names.value); |
185 .reduce(AnnotationType.NONE, this::combineAnnotationType); |
171 if (!(atValue instanceof Attribute.Array)) { |
186 } |
172 Assert.error("annotationType(): bad @Target argument " + atValue + |
187 |
173 " (" + atValue.getClass() + ")"); |
188 private AnnotationType combineAnnotationType(AnnotationType at1, AnnotationType at2) { |
174 return AnnotationType.DECLARATION; // error recovery |
189 if (at1 == AnnotationType.NONE) { |
175 } |
190 return at2; |
176 Attribute.Array arr = (Attribute.Array) atValue; |
191 } else if (at2 == AnnotationType.NONE) { |
177 boolean isDecl = false, isType = false; |
192 return at1; |
178 for (Attribute app : arr.values) { |
193 } else if (at1 != at2) { |
179 if (!(app instanceof Attribute.Enum)) { |
|
180 Assert.error("annotationType(): unrecognized Attribute kind " + app + |
|
181 " (" + app.getClass() + ")"); |
|
182 isDecl = true; |
|
183 continue; |
|
184 } |
|
185 Attribute.Enum e = (Attribute.Enum) app; |
|
186 if (e.value.name == names.TYPE) { |
|
187 if (s.kind == TYP) |
|
188 isDecl = true; |
|
189 } else if (e.value.name == names.FIELD) { |
|
190 if (s.kind == VAR && |
|
191 s.owner.kind != MTH) |
|
192 isDecl = true; |
|
193 } else if (e.value.name == names.METHOD) { |
|
194 if (s.kind == MTH && |
|
195 !s.isConstructor()) |
|
196 isDecl = true; |
|
197 } else if (e.value.name == names.PARAMETER) { |
|
198 if (s.kind == VAR && |
|
199 s.owner.kind == MTH && |
|
200 (s.flags() & Flags.PARAMETER) != 0) |
|
201 isDecl = true; |
|
202 } else if (e.value.name == names.CONSTRUCTOR) { |
|
203 if (s.kind == MTH && |
|
204 s.isConstructor()) |
|
205 isDecl = true; |
|
206 } else if (e.value.name == names.LOCAL_VARIABLE) { |
|
207 if (s.kind == VAR && |
|
208 s.owner.kind == MTH && |
|
209 (s.flags() & Flags.PARAMETER) == 0) |
|
210 isDecl = true; |
|
211 } else if (e.value.name == names.ANNOTATION_TYPE) { |
|
212 if (s.kind == TYP && |
|
213 (s.flags() & Flags.ANNOTATION) != 0) |
|
214 isDecl = true; |
|
215 } else if (e.value.name == names.PACKAGE) { |
|
216 if (s.kind == PCK) |
|
217 isDecl = true; |
|
218 } else if (e.value.name == names.TYPE_USE) { |
|
219 if (s.kind == TYP || |
|
220 s.kind == VAR || |
|
221 (s.kind == MTH && !s.isConstructor() && |
|
222 !s.type.getReturnType().hasTag(TypeTag.VOID)) || |
|
223 (s.kind == MTH && s.isConstructor())) |
|
224 isType = true; |
|
225 } else if (e.value.name == names.TYPE_PARAMETER) { |
|
226 /* Irrelevant in this case */ |
|
227 // TYPE_PARAMETER doesn't aid in distinguishing between |
|
228 // Type annotations and declaration annotations on an |
|
229 // Element |
|
230 } else { |
|
231 Assert.error("annotationType(): unrecognized Attribute name " + e.value.name + |
|
232 " (" + e.value.name.getClass() + ")"); |
|
233 isDecl = true; |
|
234 } |
|
235 } |
|
236 if (isDecl && isType) { |
|
237 return AnnotationType.BOTH; |
194 return AnnotationType.BOTH; |
238 } else if (isType) { |
|
239 return AnnotationType.TYPE; |
|
240 } else { |
195 } else { |
|
196 return at1; |
|
197 } |
|
198 } |
|
199 |
|
200 private AnnotationType targetToAnnotationType(Attribute a, Symbol s) { |
|
201 Attribute.Enum e = (Attribute.Enum)a; |
|
202 if (e.value.name == names.TYPE) { |
|
203 if (s.kind == TYP) |
|
204 return AnnotationType.DECLARATION; |
|
205 } else if (e.value.name == names.FIELD) { |
|
206 if (s.kind == VAR && |
|
207 s.owner.kind != MTH) |
|
208 return AnnotationType.DECLARATION; |
|
209 } else if (e.value.name == names.METHOD) { |
|
210 if (s.kind == MTH && |
|
211 !s.isConstructor()) |
|
212 return AnnotationType.DECLARATION; |
|
213 } else if (e.value.name == names.PARAMETER) { |
|
214 if (s.kind == VAR && |
|
215 s.owner.kind == MTH && |
|
216 (s.flags() & Flags.PARAMETER) != 0) |
|
217 return AnnotationType.DECLARATION; |
|
218 } else if (e.value.name == names.CONSTRUCTOR) { |
|
219 if (s.kind == MTH && |
|
220 s.isConstructor()) |
|
221 return AnnotationType.DECLARATION; |
|
222 } else if (e.value.name == names.LOCAL_VARIABLE) { |
|
223 if (s.kind == VAR && |
|
224 s.owner.kind == MTH && |
|
225 (s.flags() & Flags.PARAMETER) == 0) |
|
226 return AnnotationType.DECLARATION; |
|
227 } else if (e.value.name == names.ANNOTATION_TYPE) { |
|
228 if (s.kind == TYP && |
|
229 (s.flags() & Flags.ANNOTATION) != 0) |
|
230 return AnnotationType.DECLARATION; |
|
231 } else if (e.value.name == names.PACKAGE) { |
|
232 if (s.kind == PCK) |
|
233 return AnnotationType.DECLARATION; |
|
234 } else if (e.value.name == names.TYPE_USE) { |
|
235 if (s.kind == TYP || |
|
236 s.kind == VAR || |
|
237 (s.kind == MTH && !s.isConstructor() && |
|
238 !s.type.getReturnType().hasTag(TypeTag.VOID)) || |
|
239 (s.kind == MTH && s.isConstructor())) |
|
240 return AnnotationType.TYPE; |
|
241 } else if (e.value.name == names.TYPE_PARAMETER) { |
|
242 /* Irrelevant in this case */ |
|
243 // TYPE_PARAMETER doesn't aid in distinguishing between |
|
244 // Type annotations and declaration annotations on an |
|
245 // Element |
|
246 } else { |
|
247 Assert.error("annotationTargetType(): unrecognized Attribute name " + e.value.name + |
|
248 " (" + e.value.name.getClass() + ")"); |
241 return AnnotationType.DECLARATION; |
249 return AnnotationType.DECLARATION; |
242 } |
250 } |
|
251 return AnnotationType.NONE; |
243 } |
252 } |
244 |
|
245 /** Infer the target annotation kind, if none is give. |
|
246 * We only infer declaration annotations. |
|
247 */ |
|
248 private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) { |
|
249 return AnnotationType.DECLARATION; |
|
250 } |
|
251 |
|
252 |
253 |
253 private class TypeAnnotationPositions extends TreeScanner { |
254 private class TypeAnnotationPositions extends TreeScanner { |
254 |
255 |
255 private final boolean sigOnly; |
256 private final boolean sigOnly; |
256 |
257 |
260 |
261 |
261 /* |
262 /* |
262 * When traversing the AST we keep the "frames" of visited |
263 * When traversing the AST we keep the "frames" of visited |
263 * trees in order to determine the position of annotations. |
264 * trees in order to determine the position of annotations. |
264 */ |
265 */ |
265 private ListBuffer<JCTree> frames = new ListBuffer<>(); |
266 private List<JCTree> frames = List.nil(); |
266 |
267 |
267 protected void push(JCTree t) { frames = frames.prepend(t); } |
268 protected void push(JCTree t) { |
268 protected JCTree pop() { return frames.next(); } |
269 frames = frames.prepend(t); |
|
270 } |
|
271 protected JCTree pop() { |
|
272 JCTree t = frames.head; |
|
273 frames = frames.tail; |
|
274 return t; |
|
275 } |
269 // could this be frames.elems.tail.head? |
276 // could this be frames.elems.tail.head? |
270 private JCTree peek2() { return frames.toList().tail.head; } |
277 private JCTree peek2() { |
|
278 return frames.tail.head; |
|
279 } |
271 |
280 |
272 @Override |
281 @Override |
273 public void scan(JCTree tree) { |
282 public void scan(JCTree tree) { |
274 push(tree); |
283 push(tree); |
275 super.scan(tree); |
284 try { |
276 pop(); |
285 super.scan(tree); |
|
286 } finally { |
|
287 pop(); |
|
288 } |
277 } |
289 } |
278 |
290 |
279 /** |
291 /** |
280 * Separates type annotations from declaration annotations. |
292 * Separates type annotations from declaration annotations. |
281 * This step is needed because in certain locations (where declaration |
293 * This step is needed because in certain locations (where declaration |
282 * and type annotations can be mixed, e.g. the type of a field) |
294 * and type annotations can be mixed, e.g. the type of a field) |
283 * we never build an JCAnnotatedType. This step finds these |
295 * we never build an JCAnnotatedType. This step finds these |
284 * annotations and marks them as if they were part of the type. |
296 * annotations and marks them as if they were part of the type. |
285 */ |
297 */ |
286 private void separateAnnotationsKinds(JCTree typetree, Type type, Symbol sym, |
298 private void separateAnnotationsKinds(JCTree typetree, Type type, |
287 TypeAnnotationPosition pos) { |
299 Symbol sym, TypeAnnotationPosition pos) |
288 List<Attribute.Compound> annotations = sym.getRawAttributes(); |
300 { |
|
301 List<Attribute.Compound> allAnnotations = sym.getRawAttributes(); |
289 ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<>(); |
302 ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<>(); |
290 ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<>(); |
303 ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<>(); |
291 ListBuffer<Attribute.TypeCompound> onlyTypeAnnos = new ListBuffer<>(); |
304 ListBuffer<Attribute.TypeCompound> onlyTypeAnnos = new ListBuffer<>(); |
292 |
305 |
293 for (Attribute.Compound a : annotations) { |
306 for (Attribute.Compound a : allAnnotations) { |
294 switch (annotationType(a, sym)) { |
307 switch (annotationTargetType(a, sym)) { |
295 case DECLARATION: |
308 case DECLARATION: |
296 declAnnos.append(a); |
309 declAnnos.append(a); |
297 break; |
310 break; |
298 case BOTH: { |
311 case BOTH: { |
299 declAnnos.append(a); |
312 declAnnos.append(a); |
300 Attribute.TypeCompound ta = toTypeCompound(a, pos); |
313 Attribute.TypeCompound ta = toTypeCompound(a, pos); |
301 typeAnnos.append(ta); |
314 typeAnnos.append(ta); |
302 break; |
315 break; |
303 } |
316 } |
304 case TYPE: { |
317 case TYPE: { |
305 Attribute.TypeCompound ta = toTypeCompound(a, pos); |
318 Attribute.TypeCompound ta = toTypeCompound(a, pos); |
306 typeAnnos.append(ta); |
319 typeAnnos.append(ta); |
307 // Also keep track which annotations are only type annotations |
320 // Also keep track which annotations are only type annotations |
308 onlyTypeAnnos.append(ta); |
321 onlyTypeAnnos.append(ta); |
309 break; |
322 break; |
310 } |
323 } |
311 } |
324 } |
312 } |
325 } |
313 |
326 |
|
327 // If we have no type annotations we are done for this Symbol |
|
328 if (typeAnnos.isEmpty()) { |
|
329 return; |
|
330 } |
|
331 |
|
332 // Reset decl annotations to the set {all - type only} |
314 sym.resetAnnotations(); |
333 sym.resetAnnotations(); |
315 sym.setDeclarationAttributes(declAnnos.toList()); |
334 sym.setDeclarationAttributes(declAnnos.toList()); |
316 |
|
317 if (typeAnnos.isEmpty()) { |
|
318 return; |
|
319 } |
|
320 |
335 |
321 List<Attribute.TypeCompound> typeAnnotations = typeAnnos.toList(); |
336 List<Attribute.TypeCompound> typeAnnotations = typeAnnos.toList(); |
322 |
337 |
323 if (type == null) { |
338 if (type == null) { |
324 // When type is null, put the type annotations to the symbol. |
339 // When type is null, put the type annotations to the symbol. |
326 // we use the type of the enclosing class. |
341 // we use the type of the enclosing class. |
327 type = sym.getEnclosingElement().asType(); |
342 type = sym.getEnclosingElement().asType(); |
328 |
343 |
329 // Declaration annotations are always allowed on constructor returns. |
344 // Declaration annotations are always allowed on constructor returns. |
330 // Therefore, use typeAnnotations instead of onlyTypeAnnos. |
345 // Therefore, use typeAnnotations instead of onlyTypeAnnos. |
331 type = typeWithAnnotations(typetree, type, typeAnnotations, typeAnnotations); |
346 typeWithAnnotations(typetree, type, typeAnnotations, typeAnnotations, pos); |
332 // Note that we don't use the result, the call to |
347 // Note that we don't use the result, the call to |
333 // typeWithAnnotations side-effects the type annotation positions. |
348 // typeWithAnnotations side-effects the type annotation positions. |
334 // This is important for constructors of nested classes. |
349 // This is important for constructors of nested classes. |
335 sym.appendUniqueTypeAttributes(typeAnnotations); |
350 sym.appendUniqueTypeAttributes(typeAnnotations); |
336 return; |
351 return; |
337 } |
352 } |
338 |
353 |
339 // type is non-null and annotations are added to that type |
354 // type is non-null, add type annotations from declaration context to the type |
340 type = typeWithAnnotations(typetree, type, typeAnnotations, onlyTypeAnnos.toList()); |
355 type = typeWithAnnotations(typetree, type, typeAnnotations, onlyTypeAnnos.toList(), pos); |
341 |
356 |
342 if (sym.getKind() == ElementKind.METHOD) { |
357 if (sym.getKind() == ElementKind.METHOD) { |
343 sym.type.asMethodType().restype = type; |
358 sym.type.asMethodType().restype = type; |
344 } else if (sym.getKind() == ElementKind.PARAMETER) { |
359 } else if (sym.getKind() == ElementKind.PARAMETER) { |
345 sym.type = type; |
360 sym.type = type; |
388 // |
403 // |
389 // As a side effect the method sets the type annotation position of "annotations". |
404 // As a side effect the method sets the type annotation position of "annotations". |
390 // Note that it is assumed that all annotations share the same position. |
405 // Note that it is assumed that all annotations share the same position. |
391 private Type typeWithAnnotations(final JCTree typetree, final Type type, |
406 private Type typeWithAnnotations(final JCTree typetree, final Type type, |
392 final List<Attribute.TypeCompound> annotations, |
407 final List<Attribute.TypeCompound> annotations, |
393 final List<Attribute.TypeCompound> onlyTypeAnnotations) { |
408 final List<Attribute.TypeCompound> onlyTypeAnnotations, |
394 //System.err.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s, onlyTypeAnnotations: %s)%n", |
409 final TypeAnnotationPosition pos) |
395 // typetree, type, annotations, onlyTypeAnnotations); |
410 { |
396 if (annotations.isEmpty()) { |
411 if (annotations.isEmpty()) { |
397 return type; |
412 return type; |
398 } |
413 } |
399 if (type.hasTag(TypeTag.ARRAY)) { |
414 |
400 Type.ArrayType arType = (Type.ArrayType) type; |
415 if (type.hasTag(TypeTag.ARRAY)) |
401 Type.ArrayType tomodify = new Type.ArrayType(null, arType.tsym); |
416 return rewriteArrayType((ArrayType)type, annotations, pos); |
402 Type toreturn; |
417 |
403 if (type.isAnnotated()) { |
418 if (type.hasTag(TypeTag.TYPEVAR)) { |
404 toreturn = tomodify.annotatedType(type.getAnnotationMirrors()); |
419 return type.annotatedType(onlyTypeAnnotations); |
405 } else { |
|
406 toreturn = tomodify; |
|
407 } |
|
408 |
|
409 JCArrayTypeTree arTree = arrayTypeTree(typetree); |
|
410 |
|
411 ListBuffer<TypePathEntry> depth = new ListBuffer<>(); |
|
412 depth = depth.append(TypePathEntry.ARRAY); |
|
413 while (arType.elemtype.hasTag(TypeTag.ARRAY)) { |
|
414 if (arType.elemtype.isAnnotated()) { |
|
415 Type aelemtype = arType.elemtype; |
|
416 arType = (Type.ArrayType) aelemtype; |
|
417 ArrayType prevToMod = tomodify; |
|
418 tomodify = new Type.ArrayType(null, arType.tsym); |
|
419 prevToMod.elemtype = tomodify.annotatedType(arType.elemtype.getAnnotationMirrors()); |
|
420 } else { |
|
421 arType = (Type.ArrayType) arType.elemtype; |
|
422 tomodify.elemtype = new Type.ArrayType(null, arType.tsym); |
|
423 tomodify = (Type.ArrayType) tomodify.elemtype; |
|
424 } |
|
425 arTree = arrayTypeTree(arTree.elemtype); |
|
426 depth = depth.append(TypePathEntry.ARRAY); |
|
427 } |
|
428 Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, onlyTypeAnnotations); |
|
429 tomodify.elemtype = arelemType; |
|
430 { |
|
431 // All annotations share the same position; modify the first one. |
|
432 Attribute.TypeCompound a = annotations.get(0); |
|
433 TypeAnnotationPosition p = a.position; |
|
434 p.location = p.location.prependList(depth.toList()); |
|
435 } |
|
436 typetree.type = toreturn; |
|
437 return toreturn; |
|
438 } else if (type.hasTag(TypeTag.TYPEVAR)) { |
|
439 // Nothing to do for type variables. |
|
440 return type; |
|
441 } else if (type.getKind() == TypeKind.UNION) { |
420 } else if (type.getKind() == TypeKind.UNION) { |
442 // There is a TypeKind, but no TypeTag. |
421 // There is a TypeKind, but no TypeTag. |
443 JCTypeUnion tutree = (JCTypeUnion) typetree; |
422 JCTypeUnion tutree = (JCTypeUnion)typetree; |
444 JCExpression fst = tutree.alternatives.get(0); |
423 JCExpression fst = tutree.alternatives.get(0); |
445 Type res = typeWithAnnotations(fst, fst.type, annotations, onlyTypeAnnotations); |
424 Type res = typeWithAnnotations(fst, fst.type, annotations, onlyTypeAnnotations, pos); |
446 fst.type = res; |
425 fst.type = res; |
447 // TODO: do we want to set res as first element in uct.alternatives? |
426 // TODO: do we want to set res as first element in uct.alternatives? |
448 // UnionClassType uct = (com.sun.tools.javac.code.Type.UnionClassType)type; |
427 // UnionClassType uct = (com.sun.tools.javac.code.Type.UnionClassType)type; |
449 // Return the un-annotated union-type. |
428 // Return the un-annotated union-type. |
450 return type; |
429 return type; |
537 typetree.type = ret; |
516 typetree.type = ret; |
538 return ret; |
517 return ret; |
539 } |
518 } |
540 } |
519 } |
541 |
520 |
542 private JCArrayTypeTree arrayTypeTree(JCTree typetree) { |
521 /** |
543 if (typetree.getKind() == JCTree.Kind.ARRAY_TYPE) { |
522 * Create a copy of the {@code Type type} with the help of the Tree for a type |
544 return (JCArrayTypeTree) typetree; |
523 * {@code JCTree typetree} inserting all type annotations in {@code annotations} to the |
545 } else if (typetree.getKind() == JCTree.Kind.ANNOTATED_TYPE) { |
524 * innermost array component type. |
546 return (JCArrayTypeTree) ((JCAnnotatedType)typetree).underlyingType; |
525 * |
|
526 * SIDE EFFECT: Update position for the annotations to be {@code pos}. |
|
527 */ |
|
528 private Type rewriteArrayType(ArrayType type, List<TypeCompound> annotations, TypeAnnotationPosition pos) { |
|
529 ArrayType tomodify = new ArrayType(type); |
|
530 ArrayType res = tomodify; |
|
531 |
|
532 List<TypePathEntry> loc = List.nil(); |
|
533 |
|
534 // peel one and update loc |
|
535 Type tmpType = type.elemtype; |
|
536 loc = loc.prepend(TypePathEntry.ARRAY); |
|
537 |
|
538 while (tmpType.hasTag(TypeTag.ARRAY)) { |
|
539 ArrayType arr = (ArrayType)tmpType; |
|
540 |
|
541 // Update last type with new element type |
|
542 ArrayType tmp = new ArrayType(arr); |
|
543 tomodify.elemtype = tmp; |
|
544 tomodify = tmp; |
|
545 |
|
546 tmpType = arr.elemtype; |
|
547 loc = loc.prepend(TypePathEntry.ARRAY); |
|
548 } |
|
549 |
|
550 // Fix innermost element type |
|
551 Type elemType; |
|
552 if (tmpType.getMetadata() != null) { |
|
553 List<TypeCompound> tcs; |
|
554 if (tmpType.getAnnotationMirrors().isEmpty()) { |
|
555 tcs = annotations; |
|
556 } else { |
|
557 // Special case, lets prepend |
|
558 tcs = annotations.appendList(tmpType.getAnnotationMirrors()); |
|
559 } |
|
560 elemType = tmpType.cloneWithMetadata(tmpType |
|
561 .getMetadata() |
|
562 .without(Kind.ANNOTATIONS) |
|
563 .combine(new TypeMetadata.Annotations(tcs))); |
547 } else { |
564 } else { |
548 Assert.error("Could not determine array type from type tree: " + typetree); |
565 elemType = tmpType.cloneWithMetadata(new TypeMetadata(new TypeMetadata.Annotations(annotations))); |
549 return null; |
566 } |
550 } |
567 tomodify.elemtype = elemType; |
|
568 |
|
569 // Update positions |
|
570 for (TypeCompound tc : annotations) { |
|
571 if (tc.position == null) |
|
572 tc.position = pos; |
|
573 tc.position.location = loc; |
|
574 } |
|
575 |
|
576 return res; |
551 } |
577 } |
552 |
578 |
553 /** Return a copy of the first type that only differs by |
579 /** Return a copy of the first type that only differs by |
554 * inserting the annotations to the left-most/inner-most type |
580 * inserting the annotations to the left-most/inner-most type |
555 * or the type given by stopAt. |
581 * or the type given by stopAt. |
693 case NEW_CLASS: |
712 case NEW_CLASS: |
694 final JCNewClass frameNewClass = (JCNewClass) frame; |
713 final JCNewClass frameNewClass = (JCNewClass) frame; |
695 if (frameNewClass.def != null) { |
714 if (frameNewClass.def != null) { |
696 // Special handling for anonymous class instantiations |
715 // Special handling for anonymous class instantiations |
697 final JCClassDecl frameClassDecl = frameNewClass.def; |
716 final JCClassDecl frameClassDecl = frameNewClass.def; |
698 if (frameClassDecl.extending == tree) { |
717 if (frameClassDecl.implementing.contains(tree)) { |
699 return TypeAnnotationPosition |
|
700 .classExtends(location.toList(), currentLambda, |
|
701 frame.pos); |
|
702 } else if (frameClassDecl.implementing.contains(tree)) { |
|
703 final int type_index = |
718 final int type_index = |
704 frameClassDecl.implementing.indexOf(tree); |
719 frameClassDecl.implementing.indexOf(tree); |
705 return TypeAnnotationPosition |
720 return TypeAnnotationPosition |
706 .classExtends(location.toList(), currentLambda, |
721 .classExtends(location.toList(), currentLambda, |
707 type_index, frame.pos); |
722 type_index, frame.pos); |
708 } else { |
723 } else { |
709 // In contrast to CLASS below, typarams cannot occur here. |
724 //for encl.new @TA Clazz(), tree may be different from frameClassDecl.extending |
710 throw new AssertionError("Could not determine position of tree " + tree + |
725 return TypeAnnotationPosition |
711 " within frame " + frame); |
726 .classExtends(location.toList(), currentLambda, |
|
727 frame.pos); |
712 } |
728 } |
713 } else if (frameNewClass.typeargs.contains(tree)) { |
729 } else if (frameNewClass.typeargs.contains(tree)) { |
714 final int type_index = |
730 final int type_index = |
715 frameNewClass.typeargs.indexOf(tree); |
731 frameNewClass.typeargs.indexOf(tree); |
716 return TypeAnnotationPosition |
732 return TypeAnnotationPosition |
1118 if (tree.recvparam != null && tree.recvparam.sym != null && |
1134 if (tree.recvparam != null && tree.recvparam.sym != null && |
1119 !tree.recvparam.mods.annotations.isEmpty()) { |
1135 !tree.recvparam.mods.annotations.isEmpty()) { |
1120 // Nothing to do for separateAnnotationsKinds if |
1136 // Nothing to do for separateAnnotationsKinds if |
1121 // there are no annotations of either kind. |
1137 // there are no annotations of either kind. |
1122 // TODO: make sure there are no declaration annotations. |
1138 // TODO: make sure there are no declaration annotations. |
1123 final TypeAnnotationPosition pos = |
1139 final TypeAnnotationPosition pos = TypeAnnotationPosition.methodReceiver(tree.recvparam.vartype.pos); |
1124 TypeAnnotationPosition.methodReceiver(tree.recvparam.vartype.pos); |
1140 push(tree.recvparam); |
1125 separateAnnotationsKinds(tree.recvparam.vartype, |
1141 try { |
1126 tree.recvparam.sym.type, |
1142 separateAnnotationsKinds(tree.recvparam.vartype, tree.recvparam.sym.type, tree.recvparam.sym, pos); |
1127 tree.recvparam.sym, pos); |
1143 } finally { |
|
1144 pop(); |
|
1145 } |
1128 } |
1146 } |
1129 int i = 0; |
1147 int i = 0; |
1130 for (JCVariableDecl param : tree.params) { |
1148 for (JCVariableDecl param : tree.params) { |
1131 if (!param.mods.annotations.isEmpty()) { |
1149 if (!param.mods.annotations.isEmpty()) { |
1132 // Nothing to do for separateAnnotationsKinds if |
1150 // Nothing to do for separateAnnotationsKinds if |
1133 // there are no annotations of either kind. |
1151 // there are no annotations of either kind. |
1134 final TypeAnnotationPosition pos = |
1152 final TypeAnnotationPosition pos = TypeAnnotationPosition.methodParameter(i, param.vartype.pos); |
1135 TypeAnnotationPosition.methodParameter(i, param.vartype.pos); |
1153 push(param); |
1136 separateAnnotationsKinds(param.vartype, |
1154 try { |
1137 param.sym.type, |
1155 separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos); |
1138 param.sym, pos); |
1156 } finally { |
|
1157 pop(); |
|
1158 } |
1139 } |
1159 } |
1140 ++i; |
1160 ++i; |
1141 } |
1161 } |
1142 } |
1162 } |
1143 |
1163 |
1144 push(tree); |
|
1145 // super.visitMethodDef(tree); |
|
1146 if (sigOnly) { |
1164 if (sigOnly) { |
1147 scan(tree.mods); |
1165 scan(tree.mods); |
1148 scan(tree.restype); |
1166 scan(tree.restype); |
1149 scan(tree.typarams); |
1167 scan(tree.typarams); |
1150 scan(tree.recvparam); |
1168 scan(tree.recvparam); |
1361 } |
1377 } |
1362 } |
1378 } |
1363 scan(tree.elems); |
1379 scan(tree.elems); |
1364 } |
1380 } |
1365 |
1381 |
|
1382 |
|
1383 private void findTypeCompoundPosition(JCTree tree, JCTree frame, List<Attribute.TypeCompound> annotations) { |
|
1384 if (!annotations.isEmpty()) { |
|
1385 final TypeAnnotationPosition p = |
|
1386 resolveFrame(tree, frame, frames, currentLambda, 0, new ListBuffer<>()); |
|
1387 for (TypeCompound tc : annotations) |
|
1388 tc.position = p; |
|
1389 } |
|
1390 } |
|
1391 |
1366 private void findPosition(JCTree tree, JCTree frame, List<JCAnnotation> annotations) { |
1392 private void findPosition(JCTree tree, JCTree frame, List<JCAnnotation> annotations) { |
1367 if (!annotations.isEmpty()) { |
1393 if (!annotations.isEmpty()) |
1368 /* |
1394 { |
1369 System.err.println("Finding pos for: " + annotations); |
|
1370 System.err.println(" tree: " + tree + " kind: " + tree.getKind()); |
|
1371 System.err.println(" frame: " + frame + " kind: " + frame.getKind()); |
|
1372 */ |
|
1373 final TypeAnnotationPosition p = |
1395 final TypeAnnotationPosition p = |
1374 resolveFrame(tree, frame, frames.toList(), currentLambda, 0, |
1396 resolveFrame(tree, frame, frames, currentLambda, 0, new ListBuffer<>()); |
1375 new ListBuffer<TypePathEntry>()); |
1397 |
1376 setTypeAnnotationPos(annotations, p); |
1398 setTypeAnnotationPos(annotations, p); |
1377 } |
1399 } |
1378 } |
1400 } |
1379 |
1401 |
1380 private void setTypeAnnotationPos(List<JCAnnotation> annotations, |
1402 private void setTypeAnnotationPos(List<JCAnnotation> annotations, TypeAnnotationPosition position) |
1381 TypeAnnotationPosition position) { |
1403 { |
|
1404 // attribute might be null during DeferredAttr; |
|
1405 // we will be back later. |
1382 for (JCAnnotation anno : annotations) { |
1406 for (JCAnnotation anno : annotations) { |
1383 // attribute might be null during DeferredAttr; |
1407 if (anno.attribute != null) |
1384 // we will be back later. |
|
1385 if (anno.attribute != null) { |
|
1386 ((Attribute.TypeCompound) anno.attribute).position = position; |
1408 ((Attribute.TypeCompound) anno.attribute).position = position; |
1387 } |
1409 } |
1388 } |
1410 } |
1389 } |
1411 |
1390 |
1412 |
1391 @Override |
1413 @Override |
1392 public String toString() { |
1414 public String toString() { |
1393 return super.toString() + ": sigOnly: " + sigOnly; |
1415 return super.toString() + ": sigOnly: " + sigOnly; |
1394 } |
1416 } |