< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java

Print this page




  60 import com.sun.tools.javac.tree.TreeInfo;
  61 import com.sun.tools.javac.tree.JCTree.JCBlock;
  62 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
  63 import com.sun.tools.javac.tree.JCTree.JCExpression;
  64 import com.sun.tools.javac.tree.JCTree.JCLambda;
  65 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
  66 import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
  67 import com.sun.tools.javac.tree.JCTree.JCNewClass;
  68 import com.sun.tools.javac.tree.JCTree.JCTypeApply;
  69 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
  70 import com.sun.tools.javac.tree.TreeScanner;
  71 import com.sun.tools.javac.tree.JCTree.*;
  72 import com.sun.tools.javac.util.Assert;
  73 import com.sun.tools.javac.util.Context;
  74 import com.sun.tools.javac.util.List;
  75 import com.sun.tools.javac.util.ListBuffer;
  76 import com.sun.tools.javac.util.Log;
  77 import com.sun.tools.javac.util.Names;
  78 
  79 import static com.sun.tools.javac.code.Kinds.Kind.*;

  80 
  81 /**
  82  * Contains operations specific to processing type annotations.
  83  * This class has two functions:
  84  * separate declaration from type annotations and insert the type
  85  * annotations to their types;
  86  * and determine the TypeAnnotationPositions for all type annotations.
  87  */
  88 public class TypeAnnotations {
  89     protected static final Context.Key<TypeAnnotations> typeAnnosKey = new Context.Key<>();
  90 
  91     public static TypeAnnotations instance(Context context) {
  92         TypeAnnotations instance = context.get(typeAnnosKey);
  93         if (instance == null)
  94             instance = new TypeAnnotations(context);
  95         return instance;
  96     }
  97 
  98     final Log log;
  99     final Names names;


 373                         if (params.head == sym) {
 374                             newArgs.add(type);
 375                         } else {
 376                             newArgs.add(oldArgs.head);
 377                         }
 378                         oldArgs = oldArgs.tail;
 379                         params = params.tail;
 380                     }
 381                     methType.argtypes = newArgs.toList();
 382                 }
 383             } else {
 384                 sym.type = type;
 385             }
 386 
 387             sym.appendUniqueTypeAttributes(typeAnnotations);
 388 
 389             if (sym.getKind() == ElementKind.PARAMETER ||
 390                 sym.getKind() == ElementKind.LOCAL_VARIABLE ||
 391                 sym.getKind() == ElementKind.RESOURCE_VARIABLE ||
 392                 sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
 393                 // Make sure all type annotations from the symbol are also
 394                 // on the owner. If the owner is an initializer block, propagate
 395                 // to the type.
 396                 final long ownerFlags = sym.owner.flags();
 397                 if ((ownerFlags & Flags.BLOCK) != 0) {
 398                     // Store init and clinit type annotations with the ClassSymbol
 399                     // to allow output in Gen.normalizeDefs.
 400                     ClassSymbol cs = (ClassSymbol) sym.owner.owner;
 401                     if ((ownerFlags & Flags.STATIC) != 0) {
 402                         cs.appendClassInitTypeAttributes(typeAnnotations);
 403                     } else {
 404                         cs.appendInitTypeAttributes(typeAnnotations);
 405                     }


 406                 } else {
 407                     sym.owner.appendUniqueTypeAttributes(sym.getRawTypeAttributes());
 408                 }


 409             }
 410         }
 411 
 412         // This method has a similar purpose as
 413         // {@link com.sun.tools.javac.parser.JavacParser.insertAnnotationsToMostInner(JCExpression, List<JCTypeAnnotation>, boolean)}
 414         // We found a type annotation in a declaration annotation position,
 415         // for example, on the return type.
 416         // Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore
 417         // need to set its position explicitly.
 418         // The method returns a copy of type that contains these annotations.
 419         //
 420         // As a side effect the method sets the type annotation position of "annotations".
 421         // Note that it is assumed that all annotations share the same position.
 422         private Type typeWithAnnotations(final JCTree typetree, final Type type,
 423                 final List<Attribute.TypeCompound> annotations,
 424                 final List<Attribute.TypeCompound> onlyTypeAnnotations,
 425                 final TypeAnnotationPosition pos)
 426         {
 427             if (annotations.isEmpty()) {
 428                 return type;


 926                         final JCMethodDecl method =
 927                             (JCMethodDecl)path.tail.tail.head;
 928                         final int parameter_index =
 929                             method.typarams.indexOf(path.tail.head);
 930                         final int bound_index =
 931                             ((JCTypeParameter)frame).bounds.get(0)
 932                             .type.isInterface() ?
 933                             ((JCTypeParameter)frame).bounds.indexOf(tree) + 1:
 934                             ((JCTypeParameter)frame).bounds.indexOf(tree);
 935                         return TypeAnnotationPosition
 936                             .methodTypeParameterBound(location.toList(),
 937                                                       currentLambda,
 938                                                       parameter_index,
 939                                                       bound_index,
 940                                                       frame.pos);
 941                     } else {
 942                         throw new AssertionError("Could not determine position of tree " + tree +
 943                                                  " within frame " + frame);
 944                     }
 945 

 946                 case VARIABLE:
 947                     VarSymbol v = ((JCVariableDecl)frame).sym;
 948                     if (v.getKind() != ElementKind.FIELD) {
 949                         v.owner.appendUniqueTypeAttributes(v.getRawTypeAttributes());
 950                     }
 951                     switch (v.getKind()) {
 952                         case LOCAL_VARIABLE:
 953                             return TypeAnnotationPosition
 954                                 .localVariable(location.toList(), currentLambda,
 955                                                frame.pos);
 956                         case FIELD:
 957                             return TypeAnnotationPosition.field(location.toList(),
 958                                                                 currentLambda,
 959                                                                 frame.pos);
 960                         case PARAMETER:
 961                             if (v.getQualifiedName().equals(names._this)) {
 962                                 return TypeAnnotationPosition
 963                                     .methodReceiver(location.toList(),
 964                                                     currentLambda,
 965                                                     frame.pos);
 966                             } else {
 967                                 final int parameter_index =
 968                                     methodParamIndex(path, frame);
 969                                 return TypeAnnotationPosition


1249                 final TypeAnnotationPosition pos =
1250                     TypeAnnotationPosition.localVariable(currentLambda,
1251                                                          tree.pos);
1252                 if (!tree.isImplicitlyTyped()) {
1253                     separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
1254                 }
1255             } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
1256                 final TypeAnnotationPosition pos =
1257                     TypeAnnotationPosition.exceptionParameter(currentLambda,
1258                                                               tree.pos);
1259                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
1260             } else if (tree.sym.getKind() == ElementKind.RESOURCE_VARIABLE) {
1261                 final TypeAnnotationPosition pos =
1262                     TypeAnnotationPosition.resourceVariable(currentLambda,
1263                                                             tree.pos);
1264                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
1265             } else if (tree.sym.getKind() == ElementKind.ENUM_CONSTANT) {
1266                 // No type annotations can occur here.
1267             } else {
1268                 // There is nothing else in a variable declaration that needs separation.
1269                 Assert.error("Unhandled variable kind");
1270             }
1271 
1272             scan(tree.mods);
1273             scan(tree.vartype);
1274             if (!sigOnly) {
1275                 scan(tree.init);
1276             }
1277         }
1278 
1279         @Override
1280         public void visitBlock(JCBlock tree) {
1281             // Do not descend into top-level blocks when only interested
1282             // in the signature.
1283             if (!sigOnly) {
1284                 scan(tree.stats);
1285             }
1286         }
1287 
1288         @Override
1289         public void visitAnnotatedType(JCAnnotatedType tree) {




  60 import com.sun.tools.javac.tree.TreeInfo;
  61 import com.sun.tools.javac.tree.JCTree.JCBlock;
  62 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
  63 import com.sun.tools.javac.tree.JCTree.JCExpression;
  64 import com.sun.tools.javac.tree.JCTree.JCLambda;
  65 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
  66 import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
  67 import com.sun.tools.javac.tree.JCTree.JCNewClass;
  68 import com.sun.tools.javac.tree.JCTree.JCTypeApply;
  69 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
  70 import com.sun.tools.javac.tree.TreeScanner;
  71 import com.sun.tools.javac.tree.JCTree.*;
  72 import com.sun.tools.javac.util.Assert;
  73 import com.sun.tools.javac.util.Context;
  74 import com.sun.tools.javac.util.List;
  75 import com.sun.tools.javac.util.ListBuffer;
  76 import com.sun.tools.javac.util.Log;
  77 import com.sun.tools.javac.util.Names;
  78 
  79 import static com.sun.tools.javac.code.Kinds.Kind.*;
  80 import com.sun.tools.javac.tree.JCTree;
  81 
  82 /**
  83  * Contains operations specific to processing type annotations.
  84  * This class has two functions:
  85  * separate declaration from type annotations and insert the type
  86  * annotations to their types;
  87  * and determine the TypeAnnotationPositions for all type annotations.
  88  */
  89 public class TypeAnnotations {
  90     protected static final Context.Key<TypeAnnotations> typeAnnosKey = new Context.Key<>();
  91 
  92     public static TypeAnnotations instance(Context context) {
  93         TypeAnnotations instance = context.get(typeAnnosKey);
  94         if (instance == null)
  95             instance = new TypeAnnotations(context);
  96         return instance;
  97     }
  98 
  99     final Log log;
 100     final Names names;


 374                         if (params.head == sym) {
 375                             newArgs.add(type);
 376                         } else {
 377                             newArgs.add(oldArgs.head);
 378                         }
 379                         oldArgs = oldArgs.tail;
 380                         params = params.tail;
 381                     }
 382                     methType.argtypes = newArgs.toList();
 383                 }
 384             } else {
 385                 sym.type = type;
 386             }
 387 
 388             sym.appendUniqueTypeAttributes(typeAnnotations);
 389 
 390             if (sym.getKind() == ElementKind.PARAMETER ||
 391                 sym.getKind() == ElementKind.LOCAL_VARIABLE ||
 392                 sym.getKind() == ElementKind.RESOURCE_VARIABLE ||
 393                 sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
 394                 appendTypeAnnotationsToOwner(sym, typeAnnotations);
 395             }
 396         }
 397 
 398         private void appendTypeAnnotationsToOwner(Symbol sym, List<Attribute.TypeCompound> typeAnnotations) {
 399             // Make sure all type annotations from the symbol are also
 400             // on the owner. If the owner is an initializer block, propagate
 401             // to the type.
 402             final long ownerFlags = sym.owner.flags();
 403             if ((ownerFlags & Flags.BLOCK) != 0) {
 404                 // Store init and clinit type annotations with the ClassSymbol
 405                 // to allow output in Gen.normalizeDefs.
 406                 ClassSymbol cs = (ClassSymbol) sym.owner.owner;
 407                 if ((ownerFlags & Flags.STATIC) != 0) {
 408                     cs.appendClassInitTypeAttributes(typeAnnotations);
 409                 } else {
 410                     cs.appendInitTypeAttributes(typeAnnotations);
 411                 }
 412             } else {
 413                 sym.owner.appendUniqueTypeAttributes(typeAnnotations);
 414             }
 415         }
 416 
 417         // This method has a similar purpose as
 418         // {@link com.sun.tools.javac.parser.JavacParser.insertAnnotationsToMostInner(JCExpression, List<JCTypeAnnotation>, boolean)}
 419         // We found a type annotation in a declaration annotation position,
 420         // for example, on the return type.
 421         // Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore
 422         // need to set its position explicitly.
 423         // The method returns a copy of type that contains these annotations.
 424         //
 425         // As a side effect the method sets the type annotation position of "annotations".
 426         // Note that it is assumed that all annotations share the same position.
 427         private Type typeWithAnnotations(final JCTree typetree, final Type type,
 428                 final List<Attribute.TypeCompound> annotations,
 429                 final List<Attribute.TypeCompound> onlyTypeAnnotations,
 430                 final TypeAnnotationPosition pos)
 431         {
 432             if (annotations.isEmpty()) {
 433                 return type;


 931                         final JCMethodDecl method =
 932                             (JCMethodDecl)path.tail.tail.head;
 933                         final int parameter_index =
 934                             method.typarams.indexOf(path.tail.head);
 935                         final int bound_index =
 936                             ((JCTypeParameter)frame).bounds.get(0)
 937                             .type.isInterface() ?
 938                             ((JCTypeParameter)frame).bounds.indexOf(tree) + 1:
 939                             ((JCTypeParameter)frame).bounds.indexOf(tree);
 940                         return TypeAnnotationPosition
 941                             .methodTypeParameterBound(location.toList(),
 942                                                       currentLambda,
 943                                                       parameter_index,
 944                                                       bound_index,
 945                                                       frame.pos);
 946                     } else {
 947                         throw new AssertionError("Could not determine position of tree " + tree +
 948                                                  " within frame " + frame);
 949                     }
 950 
 951                 case BINDING_PATTERN:
 952                 case VARIABLE:
 953                     VarSymbol v = frame.hasTag(Tag.BINDINGPATTERN) ? ((JCBindingPattern) frame).symbol : ((JCVariableDecl) frame).sym;
 954                     if (v.getKind() != ElementKind.FIELD) {
 955                         appendTypeAnnotationsToOwner(v, v.getRawTypeAttributes());
 956                     }
 957                     switch (v.getKind()) {
 958                         case LOCAL_VARIABLE:
 959                             return TypeAnnotationPosition
 960                                 .localVariable(location.toList(), currentLambda,
 961                                                frame.pos);
 962                         case FIELD:
 963                             return TypeAnnotationPosition.field(location.toList(),
 964                                                                 currentLambda,
 965                                                                 frame.pos);
 966                         case PARAMETER:
 967                             if (v.getQualifiedName().equals(names._this)) {
 968                                 return TypeAnnotationPosition
 969                                     .methodReceiver(location.toList(),
 970                                                     currentLambda,
 971                                                     frame.pos);
 972                             } else {
 973                                 final int parameter_index =
 974                                     methodParamIndex(path, frame);
 975                                 return TypeAnnotationPosition


1255                 final TypeAnnotationPosition pos =
1256                     TypeAnnotationPosition.localVariable(currentLambda,
1257                                                          tree.pos);
1258                 if (!tree.isImplicitlyTyped()) {
1259                     separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
1260                 }
1261             } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
1262                 final TypeAnnotationPosition pos =
1263                     TypeAnnotationPosition.exceptionParameter(currentLambda,
1264                                                               tree.pos);
1265                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
1266             } else if (tree.sym.getKind() == ElementKind.RESOURCE_VARIABLE) {
1267                 final TypeAnnotationPosition pos =
1268                     TypeAnnotationPosition.resourceVariable(currentLambda,
1269                                                             tree.pos);
1270                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
1271             } else if (tree.sym.getKind() == ElementKind.ENUM_CONSTANT) {
1272                 // No type annotations can occur here.
1273             } else {
1274                 // There is nothing else in a variable declaration that needs separation.
1275                 Assert.error("Unhandled variable kind: " + tree.sym.getKind());
1276             }
1277 
1278             scan(tree.mods);
1279             scan(tree.vartype);
1280             if (!sigOnly) {
1281                 scan(tree.init);
1282             }
1283         }
1284 
1285         @Override
1286         public void visitBlock(JCBlock tree) {
1287             // Do not descend into top-level blocks when only interested
1288             // in the signature.
1289             if (!sigOnly) {
1290                 scan(tree.stats);
1291             }
1292         }
1293 
1294         @Override
1295         public void visitAnnotatedType(JCAnnotatedType tree) {


< prev index next >