< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java

Print this page

  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.comp;
  27 
  28 import java.util.HashSet;
  29 import java.util.Set;
  30 import java.util.function.BiConsumer;
  31 
  32 import javax.tools.JavaFileObject;
  33 
  34 import com.sun.tools.javac.code.*;
  35 import com.sun.tools.javac.code.Lint.LintCategory;
  36 import com.sun.tools.javac.code.Scope.ImportFilter;
  37 import com.sun.tools.javac.code.Scope.ImportScope;
  38 import com.sun.tools.javac.code.Scope.NamedImportScope;
  39 import com.sun.tools.javac.code.Scope.StarImportScope;
  40 import com.sun.tools.javac.code.Scope.WriteableScope;
  41 import com.sun.tools.javac.code.Source.Feature;
  42 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;

  43 import com.sun.tools.javac.parser.Parser;
  44 import com.sun.tools.javac.parser.ParserFactory;
  45 import com.sun.tools.javac.tree.*;
  46 import com.sun.tools.javac.util.*;
  47 import com.sun.tools.javac.util.DefinedBy.Api;
  48 
  49 import com.sun.tools.javac.code.Symbol.*;
  50 import com.sun.tools.javac.code.Type.*;
  51 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  52 import com.sun.tools.javac.tree.JCTree.*;
  53 
  54 import static com.sun.tools.javac.code.Flags.*;
  55 import static com.sun.tools.javac.code.Flags.ANNOTATION;

  56 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
  57 import static com.sun.tools.javac.code.Kinds.Kind.*;
  58 import static com.sun.tools.javac.code.TypeTag.CLASS;
  59 import static com.sun.tools.javac.code.TypeTag.ERROR;
  60 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  61 
  62 import static com.sun.tools.javac.code.TypeTag.*;
  63 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  64 
  65 import com.sun.tools.javac.util.Dependencies.CompletionCause;
  66 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  67 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  68 
  69 /** This is the second phase of Enter, in which classes are completed
  70  *  by resolving their headers and entering their members in the into
  71  *  the class scope. See Enter for an overall overview.
  72  *
  73  *  This class uses internal phases to process the classes. When a phase
  74  *  processes classes, the lower phases are not invoked until all classes
  75  *  pass through the current phase. Note that it is possible that upper phases

1123                 (types.supertype(tree.sym.type).tsym.flags() & Flags.ENUM) == 0) {
1124                 addEnumMembers(tree, env);
1125             }
1126             boolean isRecord = (tree.sym.flags_field & RECORD) != 0;
1127             List<JCTree> alreadyEntered = null;
1128             if (isRecord) {
1129                 alreadyEntered = List.convert(JCTree.class, TreeInfo.recordFields(tree));
1130                 alreadyEntered = alreadyEntered.prependList(tree.defs.stream()
1131                         .filter(t -> TreeInfo.isConstructor(t) && t != defaultConstructor).collect(List.collector()));
1132             }
1133             List<JCTree> defsToEnter = isRecord ?
1134                     tree.defs.diff(alreadyEntered) : tree.defs;
1135             memberEnter.memberEnter(defsToEnter, env);
1136             if (isRecord) {
1137                 addRecordMembersIfNeeded(tree, env);
1138             }
1139             if (tree.sym.isAnnotationType()) {
1140                 Assert.check(tree.sym.isCompleted());
1141                 tree.sym.setAnnotationTypeMetadata(new AnnotationTypeMetadata(tree.sym, annotate.annotationTypeSourceCompleter()));
1142             }











1143         }
1144 












































1145         private void addAccessor(JCVariableDecl tree, Env<AttrContext> env) {
1146             MethodSymbol implSym = lookupMethod(env.enclClass.sym, tree.sym.name, List.nil());
1147             RecordComponent rec = ((ClassSymbol) tree.sym.owner).getRecordComponent(tree.sym);
1148             if (implSym == null || (implSym.flags_field & GENERATED_MEMBER) != 0) {
1149                 /* here we are pushing the annotations present in the corresponding field down to the accessor
1150                  * it could be that some of those annotations are not applicable to the accessor, they will be striped
1151                  * away later at Check::validateAnnotation
1152                  */
1153                 TreeCopier<JCTree> tc = new TreeCopier<JCTree>(make.at(tree.pos));
1154                 List<JCAnnotation> originalAnnos = rec.getOriginalAnnos().isEmpty() ?
1155                         rec.getOriginalAnnos() :
1156                         tc.copy(rec.getOriginalAnnos());
1157                 JCVariableDecl recordField = TreeInfo.recordFields((JCClassDecl) env.tree).stream().filter(rf -> rf.name == tree.name).findAny().get();
1158                 JCMethodDecl getter = make.at(tree.pos).
1159                         MethodDef(
1160                                 make.Modifiers(PUBLIC | Flags.GENERATED_MEMBER, originalAnnos),
1161                           tree.sym.name,
1162                           /* we need to special case for the case when the user declared the type as an ident
1163                            * if we don't do that then we can have issues if type annotations are applied to the
1164                            * return type: javac issues an error if a type annotation is applied to java.lang.String

1318 
1319         @Override
1320         public Type constructorType() {
1321             if (constructorType == null) {
1322                 constructorType = new MethodType(List.nil(), syms.voidType, List.nil(), syms.methodClass);
1323             }
1324             return constructorType;
1325         }
1326 
1327         @Override
1328         public MethodSymbol constructorSymbol() {
1329             if (constructorSymbol == null) {
1330                 long flags;
1331                 if ((owner().flags() & ENUM) != 0 &&
1332                     (types.supertype(owner().type).tsym == syms.enumSym)) {
1333                     // constructors of true enums are private
1334                     flags = PRIVATE | GENERATEDCONSTR;
1335                 } else {
1336                     flags = (owner().flags() & AccessFlags) | GENERATEDCONSTR;
1337                 }
1338                 constructorSymbol = new MethodSymbol(flags, names.init,

1339                     constructorType(), owner());
1340             }
1341             return constructorSymbol;
1342         }
1343 
1344         @Override
1345         public Type enclosingType() {
1346             return Type.noType;
1347     }
1348 
1349         @Override
1350         public TypeSymbol owner() {
1351             return owner;
1352         }
1353 
1354         @Override
1355         public List<Name> superArgs() {
1356             return List.nil();
1357             }
1358     }

  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.comp;
  27 
  28 import java.util.HashSet;
  29 import java.util.Set;
  30 import java.util.function.BiConsumer;
  31 
  32 import javax.tools.JavaFileObject;
  33 
  34 import com.sun.tools.javac.code.*;
  35 import com.sun.tools.javac.code.Lint.LintCategory;
  36 import com.sun.tools.javac.code.Scope.ImportFilter;
  37 import com.sun.tools.javac.code.Scope.ImportScope;
  38 import com.sun.tools.javac.code.Scope.NamedImportScope;
  39 import com.sun.tools.javac.code.Scope.StarImportScope;
  40 import com.sun.tools.javac.code.Scope.WriteableScope;
  41 import com.sun.tools.javac.code.Source.Feature;
  42 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
  43 import com.sun.tools.javac.jvm.Target;
  44 import com.sun.tools.javac.parser.Parser;
  45 import com.sun.tools.javac.parser.ParserFactory;
  46 import com.sun.tools.javac.tree.*;
  47 import com.sun.tools.javac.util.*;
  48 import com.sun.tools.javac.util.DefinedBy.Api;
  49 
  50 import com.sun.tools.javac.code.Symbol.*;
  51 import com.sun.tools.javac.code.Type.*;
  52 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  53 import com.sun.tools.javac.tree.JCTree.*;
  54 
  55 import static com.sun.tools.javac.code.Flags.*;
  56 import static com.sun.tools.javac.code.Flags.ANNOTATION;
  57 import static com.sun.tools.javac.code.Flags.SYNCHRONIZED;
  58 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
  59 import static com.sun.tools.javac.code.Kinds.Kind.*;
  60 import static com.sun.tools.javac.code.TypeTag.CLASS;
  61 import static com.sun.tools.javac.code.TypeTag.ERROR;
  62 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  63 
  64 import static com.sun.tools.javac.code.TypeTag.*;
  65 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  66 
  67 import com.sun.tools.javac.util.Dependencies.CompletionCause;
  68 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  69 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  70 
  71 /** This is the second phase of Enter, in which classes are completed
  72  *  by resolving their headers and entering their members in the into
  73  *  the class scope. See Enter for an overall overview.
  74  *
  75  *  This class uses internal phases to process the classes. When a phase
  76  *  processes classes, the lower phases are not invoked until all classes
  77  *  pass through the current phase. Note that it is possible that upper phases

1125                 (types.supertype(tree.sym.type).tsym.flags() & Flags.ENUM) == 0) {
1126                 addEnumMembers(tree, env);
1127             }
1128             boolean isRecord = (tree.sym.flags_field & RECORD) != 0;
1129             List<JCTree> alreadyEntered = null;
1130             if (isRecord) {
1131                 alreadyEntered = List.convert(JCTree.class, TreeInfo.recordFields(tree));
1132                 alreadyEntered = alreadyEntered.prependList(tree.defs.stream()
1133                         .filter(t -> TreeInfo.isConstructor(t) && t != defaultConstructor).collect(List.collector()));
1134             }
1135             List<JCTree> defsToEnter = isRecord ?
1136                     tree.defs.diff(alreadyEntered) : tree.defs;
1137             memberEnter.memberEnter(defsToEnter, env);
1138             if (isRecord) {
1139                 addRecordMembersIfNeeded(tree, env);
1140             }
1141             if (tree.sym.isAnnotationType()) {
1142                 Assert.check(tree.sym.isCompleted());
1143                 tree.sym.setAnnotationTypeMetadata(new AnnotationTypeMetadata(tree.sym, annotate.annotationTypeSourceCompleter()));
1144             }
1145 
1146             if (tree.sym != syms.objectType.tsym && tree.sym != syms.recordType.tsym) {
1147                 if ((tree.sym.flags() & (ABSTRACT | INTERFACE | VALUE_CLASS)) == 0) {
1148                     tree.sym.flags_field |= IDENTITY_TYPE;
1149                 }
1150                 if ((tree.sym.flags() & (ABSTRACT | IDENTITY_TYPE | INTERFACE)) == ABSTRACT) {
1151                     if (abstractClassHasImplicitIdentity(tree)) {
1152                         tree.sym.flags_field |= IDENTITY_TYPE;
1153                     }
1154                 }
1155             }
1156         }
1157 
1158             // where
1159             private boolean abstractClassHasImplicitIdentity(JCClassDecl tree) {
1160 
1161                 Type t = tree.sym.type;
1162 
1163                 if (t == null || t.tsym == null || t.tsym.kind == ERR)
1164                     return false;
1165 
1166                 if ((t.tsym.flags() & HASINITBLOCK) != 0) {
1167                     return true;
1168                 }
1169 
1170                 // No instance fields and no arged constructors both mean inner classes cannot be value class supers.
1171                 Type encl = t.getEnclosingType();
1172                 if (encl != null && encl.hasTag(CLASS)) {
1173                     return true;
1174                 }
1175                 for (Symbol s : t.tsym.members().getSymbols(NON_RECURSIVE)) {
1176                     switch (s.kind) {
1177                         case VAR:
1178                             if ((s.flags() & STATIC) == 0) {
1179                                 return true;
1180                             }
1181                             break;
1182                         case MTH:
1183                             if ((s.flags() & (SYNCHRONIZED | STATIC)) == SYNCHRONIZED) {
1184                                 return true;
1185                             } else if (s.isInitOrVNew()) {
1186                                 MethodSymbol m = (MethodSymbol)s;
1187                                 if (m.getParameters().size() > 0
1188                                         || m.getTypeParameters().size() > 0
1189                                         || m.type.getThrownTypes().nonEmpty()
1190                                         || (m.flags() & EMPTYNOARGCONSTR) == 0
1191                                         || (Check.protection(m.flags()) > Check.protection(m.owner.flags()))) {
1192                                     return true;
1193                                 }
1194                             }
1195                             break;
1196                     }
1197                 }
1198                 return false;
1199             }
1200 
1201 
1202         private void addAccessor(JCVariableDecl tree, Env<AttrContext> env) {
1203             MethodSymbol implSym = lookupMethod(env.enclClass.sym, tree.sym.name, List.nil());
1204             RecordComponent rec = ((ClassSymbol) tree.sym.owner).getRecordComponent(tree.sym);
1205             if (implSym == null || (implSym.flags_field & GENERATED_MEMBER) != 0) {
1206                 /* here we are pushing the annotations present in the corresponding field down to the accessor
1207                  * it could be that some of those annotations are not applicable to the accessor, they will be striped
1208                  * away later at Check::validateAnnotation
1209                  */
1210                 TreeCopier<JCTree> tc = new TreeCopier<JCTree>(make.at(tree.pos));
1211                 List<JCAnnotation> originalAnnos = rec.getOriginalAnnos().isEmpty() ?
1212                         rec.getOriginalAnnos() :
1213                         tc.copy(rec.getOriginalAnnos());
1214                 JCVariableDecl recordField = TreeInfo.recordFields((JCClassDecl) env.tree).stream().filter(rf -> rf.name == tree.name).findAny().get();
1215                 JCMethodDecl getter = make.at(tree.pos).
1216                         MethodDef(
1217                                 make.Modifiers(PUBLIC | Flags.GENERATED_MEMBER, originalAnnos),
1218                           tree.sym.name,
1219                           /* we need to special case for the case when the user declared the type as an ident
1220                            * if we don't do that then we can have issues if type annotations are applied to the
1221                            * return type: javac issues an error if a type annotation is applied to java.lang.String

1375 
1376         @Override
1377         public Type constructorType() {
1378             if (constructorType == null) {
1379                 constructorType = new MethodType(List.nil(), syms.voidType, List.nil(), syms.methodClass);
1380             }
1381             return constructorType;
1382         }
1383 
1384         @Override
1385         public MethodSymbol constructorSymbol() {
1386             if (constructorSymbol == null) {
1387                 long flags;
1388                 if ((owner().flags() & ENUM) != 0 &&
1389                     (types.supertype(owner().type).tsym == syms.enumSym)) {
1390                     // constructors of true enums are private
1391                     flags = PRIVATE | GENERATEDCONSTR;
1392                 } else {
1393                     flags = (owner().flags() & AccessFlags) | GENERATEDCONSTR;
1394                 }
1395                 Name constructorName = owner().isConcreteValueClass() ? names.vnew : names.init;
1396                 constructorSymbol = new MethodSymbol(flags, constructorName,
1397                     constructorType(), owner());
1398             }
1399             return constructorSymbol;
1400         }
1401 
1402         @Override
1403         public Type enclosingType() {
1404             return Type.noType;
1405     }
1406 
1407         @Override
1408         public TypeSymbol owner() {
1409             return owner;
1410         }
1411 
1412         @Override
1413         public List<Name> superArgs() {
1414             return List.nil();
1415             }
1416     }
< prev index next >