< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java

Print this page

  28 import java.io.*;
  29 import java.net.URI;
  30 import java.net.URISyntaxException;
  31 import java.nio.CharBuffer;
  32 import java.nio.file.ClosedFileSystemException;
  33 import java.util.Arrays;
  34 import java.util.EnumSet;
  35 import java.util.HashMap;
  36 import java.util.HashSet;
  37 import java.util.Map;
  38 import java.util.Set;
  39 import java.util.function.IntFunction;
  40 
  41 import javax.lang.model.element.Modifier;
  42 import javax.lang.model.element.NestingKind;
  43 import javax.tools.JavaFileManager;
  44 import javax.tools.JavaFileObject;
  45 
  46 import com.sun.tools.javac.code.Source;
  47 import com.sun.tools.javac.code.Source.Feature;

  48 import com.sun.tools.javac.comp.Annotate;
  49 import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
  50 import com.sun.tools.javac.code.*;
  51 import com.sun.tools.javac.code.Directive.*;
  52 import com.sun.tools.javac.code.Lint.LintCategory;
  53 import com.sun.tools.javac.code.Scope.WriteableScope;
  54 import com.sun.tools.javac.code.Symbol.*;
  55 import com.sun.tools.javac.code.Symtab;
  56 import com.sun.tools.javac.code.Type.*;
  57 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
  58 import com.sun.tools.javac.file.BaseFileManager;
  59 import com.sun.tools.javac.file.PathFileObject;
  60 import com.sun.tools.javac.jvm.ClassFile.Version;
  61 import com.sun.tools.javac.jvm.PoolConstant.NameAndType;
  62 import com.sun.tools.javac.main.Option;
  63 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  64 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  65 import com.sun.tools.javac.util.*;
  66 import com.sun.tools.javac.util.ByteBuffer.UnderflowException;
  67 import com.sun.tools.javac.util.DefinedBy.Api;

  91  *  If you write code that depends on this, you do so at your own risk.
  92  *  This code and its internal interfaces are subject to change or
  93  *  deletion without notice.</b>
  94  */
  95 public class ClassReader {
  96     /** The context key for the class reader. */
  97     protected static final Context.Key<ClassReader> classReaderKey = new Context.Key<>();
  98 
  99     public static final int INITIAL_BUFFER_SIZE = 0x0fff0;
 100 
 101     private final Annotate annotate;
 102 
 103     /** Switch: verbose output.
 104      */
 105     boolean verbose;
 106 
 107     /** Switch: allow modules.
 108      */
 109     boolean allowModules;
 110 








 111     /** Switch: allow sealed
 112      */
 113     boolean allowSealedTypes;
 114 
 115     /** Switch: allow records
 116      */
 117     boolean allowRecords;
 118 
 119    /** Lint option: warn about classfile issues
 120      */
 121     boolean lintClassfile;
 122 
 123     /** Switch: warn (instead of error) on illegal UTF-8
 124      */
 125     boolean warnOnIllegalUtf8;
 126 
 127     /** Switch: preserve parameter names from the variable table.
 128      */
 129     public boolean saveParameterNames;
 130 

 265     protected ClassReader(Context context) {
 266         context.put(classReaderKey, this);
 267         annotate = Annotate.instance(context);
 268         names = Names.instance(context);
 269         syms = Symtab.instance(context);
 270         types = Types.instance(context);
 271         fileManager = context.get(JavaFileManager.class);
 272         if (fileManager == null)
 273             throw new AssertionError("FileManager initialization error");
 274         diagFactory = JCDiagnostic.Factory.instance(context);
 275         dcfh = DeferredCompletionFailureHandler.instance(context);
 276 
 277         log = Log.instance(context);
 278 
 279         Options options = Options.instance(context);
 280         verbose         = options.isSet(Option.VERBOSE);
 281 
 282         Source source = Source.instance(context);
 283         preview = Preview.instance(context);
 284         allowModules     = Feature.MODULES.allowedInSource(source);


 285         allowRecords = Feature.RECORDS.allowedInSource(source);
 286         allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
 287         warnOnIllegalUtf8 = Feature.WARN_ON_ILLEGAL_UTF8.allowedInSource(source);
 288 
 289         saveParameterNames = options.isSet(PARAMETERS);
 290 
 291         profile = Profile.instance(context);
 292 
 293         typevars = WriteableScope.create(syms.noSymbol);
 294 
 295         lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
 296 
 297         initAttributeReaders();
 298     }
 299 
 300     /** Add member to class unless it is synthetic.
 301      */
 302     private void enterMember(ClassSymbol c, Symbol sym) {
 303         // Synthetic members are not entered -- reason lost to history (optimization?).
 304         // Lambda methods must be entered because they may have inner classes (which reference them)

 483             return new WildcardType(t, BoundKind.SUPER, syms.boundClass);
 484         }
 485         case 'B':
 486             sigp++;
 487             return syms.byteType;
 488         case 'C':
 489             sigp++;
 490             return syms.charType;
 491         case 'D':
 492             sigp++;
 493             return syms.doubleType;
 494         case 'F':
 495             sigp++;
 496             return syms.floatType;
 497         case 'I':
 498             sigp++;
 499             return syms.intType;
 500         case 'J':
 501             sigp++;
 502             return syms.longType;

 503         case 'L':
 504             {
 505                 // int oldsigp = sigp;




 506                 Type t = classSigToType();
 507                 if (sigp < siglimit && signature[sigp] == '.')
 508                     throw badClassFile("deprecated inner class signature syntax " +
 509                                        "(please recompile from source)");
 510                 /*
 511                 System.err.println(" decoded " +
 512                                    new String(signature, oldsigp, sigp-oldsigp) +
 513                                    " => " + t + " outer " + t.outer());
 514                 */
 515                 return t;
 516             }
 517         case 'S':
 518             sigp++;
 519             return syms.shortType;
 520         case 'V':
 521             sigp++;
 522             return syms.voidType;
 523         case 'Z':
 524             sigp++;
 525             return syms.booleanType;

 543             }
 544             return new MethodType(argtypes,
 545                                   restype,
 546                                   thrown.reverse(),
 547                                   syms.methodClass);
 548         case '<':
 549             typevars = typevars.dup(currentOwner);
 550             Type poly = new ForAll(sigToTypeParams(), sigToType());
 551             typevars = typevars.leave();
 552             return poly;
 553         default:
 554             throw badClassFile("bad.signature", quoteBadSignature());
 555         }
 556     }
 557 
 558     byte[] signatureBuffer = new byte[0];
 559     int sbp = 0;
 560     /** Convert class signature to type, where signature is implicit.
 561      */
 562     Type classSigToType() {
 563         if (signature[sigp] != 'L')

 564             throw badClassFile("bad.class.signature", quoteBadSignature());
 565         sigp++;
 566         Type outer = Type.noType;


 567         int startSbp = sbp;
 568 
 569         while (true) {
 570             final byte c = signature[sigp++];
 571             switch (c) {
 572 
 573             case ';': {         // end
 574                 ClassSymbol t = enterClass(readName(signatureBuffer,
 575                                                          startSbp,
 576                                                          sbp - startSbp));
 577 


 578                 try {
 579                     return (outer == Type.noType) ?
 580                             t.erasure(types) :
 581                         new ClassType(outer, List.nil(), t);



 582                 } finally {
 583                     sbp = startSbp;
 584                 }
 585             }
 586 
 587             case '<':           // generic arguments
 588                 ClassSymbol t = enterClass(readName(signatureBuffer,
 589                                                          startSbp,
 590                                                          sbp - startSbp));
 591                 outer = new ClassType(outer, sigToTypes('>'), t) {


 592                         boolean completed = false;
 593                         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 594                         public Type getEnclosingType() {
 595                             if (!completed) {
 596                                 completed = true;
 597                                 tsym.apiComplete();
 598                                 Type enclosingType = tsym.type.getEnclosingType();
 599                                 if (enclosingType != Type.noType) {
 600                                     List<Type> typeArgs =
 601                                         super.getEnclosingType().allparams();
 602                                     List<Type> typeParams =
 603                                         enclosingType.allparams();
 604                                     if (typeParams.length() != typeArgs.length()) {
 605                                         // no "rare" types
 606                                         super.setEnclosingType(types.erasure(enclosingType));
 607                                     } else {
 608                                         super.setEnclosingType(types.subst(enclosingType,
 609                                                                            typeParams,
 610                                                                            typeArgs));
 611                                     }

 634                         signatureBuffer[sbp++] = (byte)'$';
 635                         break;
 636                     } else {
 637                         sbp = startSbp;
 638                         return outer;
 639                     }
 640                 case '.':
 641                     signatureBuffer[sbp++] = (byte)'$';
 642                     break;
 643                 default:
 644                     throw new AssertionError(signature[sigp-1]);
 645                 }
 646                 continue;
 647 
 648             case '.':
 649                 //we have seen an enclosing non-generic class
 650                 if (outer != Type.noType) {
 651                     t = enterClass(readName(signatureBuffer,
 652                                                  startSbp,
 653                                                  sbp - startSbp));
 654                     outer = new ClassType(outer, List.nil(), t);


 655                 }
 656                 signatureBuffer[sbp++] = (byte)'$';
 657                 continue;
 658             case '/':
 659                 signatureBuffer[sbp++] = (byte)'.';
 660                 continue;
 661             default:
 662                 signatureBuffer[sbp++] = c;
 663                 continue;
 664             }
 665         }
 666     }
 667 
 668     /** Quote a bogus signature for display inside an error message.
 669      */
 670     String quoteBadSignature() {
 671         String sigString;
 672         try {
 673             sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
 674         } catch (InvalidUtfException e) {

 826         protected final Name name;
 827         protected final ClassFile.Version version;
 828         protected final Set<AttributeKind> kinds;
 829     }
 830 
 831     protected Set<AttributeKind> CLASS_ATTRIBUTE =
 832             EnumSet.of(AttributeKind.CLASS);
 833     protected Set<AttributeKind> MEMBER_ATTRIBUTE =
 834             EnumSet.of(AttributeKind.MEMBER);
 835     protected Set<AttributeKind> CLASS_OR_MEMBER_ATTRIBUTE =
 836             EnumSet.of(AttributeKind.CLASS, AttributeKind.MEMBER);
 837 
 838     protected Map<Name, AttributeReader> attributeReaders = new HashMap<>();
 839 
 840     private void initAttributeReaders() {
 841         AttributeReader[] readers = {
 842             // v45.3 attributes
 843 
 844             new AttributeReader(names.Code, V45_3, MEMBER_ATTRIBUTE) {
 845                 protected void read(Symbol sym, int attrLen) {













 846                     if (saveParameterNames)
 847                         ((MethodSymbol)sym).code = readCode(sym);
 848                     else
 849                         bp = bp + attrLen;
 850                 }
 851             },
 852 
 853             new AttributeReader(names.ConstantValue, V45_3, MEMBER_ATTRIBUTE) {
 854                 protected void read(Symbol sym, int attrLen) {
 855                     Object v = poolReader.getConstant(nextChar());
 856                     // Ignore ConstantValue attribute if field not final.
 857                     if ((sym.flags() & FINAL) == 0) {
 858                         return;
 859                     }
 860                     VarSymbol var = (VarSymbol) sym;
 861                     switch (var.type.getTag()) {
 862                        case BOOLEAN:
 863                        case BYTE:
 864                        case CHAR:
 865                        case SHORT:

1005                         ClassSymbol c = (ClassSymbol) sym;
1006                         readingClassAttr = true;
1007                         try {
1008                             ClassType ct1 = (ClassType)c.type;
1009                             Assert.check(c == currentOwner);
1010                             ct1.typarams_field = poolReader.getName(nextChar())
1011                                     .map(ClassReader.this::sigToTypeParams);
1012                             ct1.supertype_field = sigToType();
1013                             ListBuffer<Type> is = new ListBuffer<>();
1014                             while (sigp != siglimit) is.append(sigToType());
1015                             ct1.interfaces_field = is.toList();
1016                         } finally {
1017                             readingClassAttr = false;
1018                         }
1019                     } else {
1020                         List<Type> thrown = sym.type.getThrownTypes();
1021                         sym.type = poolReader.getType(nextChar());
1022                         //- System.err.println(" # " + sym.type);
1023                         if (sym.kind == MTH && sym.type.getThrownTypes().isEmpty())
1024                             sym.type.asMethodType().thrown = thrown;







1025 
1026                     }
1027                 }
1028             },
1029 
1030             // v49 annotation attributes
1031 
1032             new AttributeReader(names.AnnotationDefault, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
1033                 protected void read(Symbol sym, int attrLen) {
1034                     attachAnnotationDefault(sym);
1035                 }
1036             },
1037 
1038             new AttributeReader(names.RuntimeInvisibleAnnotations, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
1039                 protected void read(Symbol sym, int attrLen) {
1040                     attachAnnotations(sym);
1041                 }
1042             },
1043 
1044             new AttributeReader(names.RuntimeInvisibleParameterAnnotations, V49, CLASS_OR_MEMBER_ATTRIBUTE) {

1358         if (simpleBinaryName.length() < 1 || simpleBinaryName.charAt(0) != '$')
1359             throw badClassFile("bad.enclosing.method", self);
1360         int index = 1;
1361         while (index < simpleBinaryName.length() &&
1362                isAsciiDigit(simpleBinaryName.charAt(index)))
1363             index++;
1364         return names.fromString(simpleBinaryName.substring(index));
1365     }
1366 
1367     private MethodSymbol findMethod(NameAndType nt, Scope scope, long flags) {
1368         if (nt == null)
1369             return null;
1370 
1371         MethodType type = nt.type.asMethodType();
1372 
1373         for (Symbol sym : scope.getSymbolsByName(nt.name)) {
1374             if (sym.kind == MTH && isSameBinaryType(sym.type.asMethodType(), type))
1375                 return (MethodSymbol)sym;
1376         }
1377 
1378         if (nt.name != names.init)
1379             // not a constructor
1380             return null;
1381         if ((flags & INTERFACE) != 0)
1382             // no enclosing instance
1383             return null;
1384         if (nt.type.getParameterTypes().isEmpty())
1385             // no parameters
1386             return null;
1387 
1388         // A constructor of an inner class.
1389         // Remove the first argument (the enclosing instance)
1390         nt = new NameAndType(nt.name, new MethodType(nt.type.getParameterTypes().tail,
1391                                  nt.type.getReturnType(),
1392                                  nt.type.getThrownTypes(),
1393                                  syms.methodClass));
1394         // Try searching again
1395         return findMethod(nt, scope, flags);
1396     }
1397 
1398     /** Similar to Types.isSameType but avoids completion */

2286     MethodSymbol readMethod() {
2287         char rawFlags = nextChar();
2288         long flags = adjustMethodFlags(rawFlags);
2289         Name name = poolReader.getName(nextChar());
2290         Type type = poolReader.getType(nextChar());
2291         if (currentOwner.isInterface() &&
2292                 (flags & ABSTRACT) == 0 && !name.equals(names.clinit)) {
2293             if (majorVersion > Version.V52.major ||
2294                     (majorVersion == Version.V52.major && minorVersion >= Version.V52.minor)) {
2295                 if ((flags & (STATIC | PRIVATE)) == 0) {
2296                     currentOwner.flags_field |= DEFAULT;
2297                     flags |= DEFAULT | ABSTRACT;
2298                 }
2299             } else {
2300                 //protect against ill-formed classfiles
2301                 throw badClassFile((flags & STATIC) == 0 ? "invalid.default.interface" : "invalid.static.interface",
2302                                    Integer.toString(majorVersion),
2303                                    Integer.toString(minorVersion));
2304             }
2305         }







2306         validateMethodType(name, type);
2307         if (name == names.init && currentOwner.hasOuterInstance()) {
2308             // Sometimes anonymous classes don't have an outer
2309             // instance, however, there is no reliable way to tell so
2310             // we never strip this$n
2311             // ditto for local classes. Local classes that have an enclosing method set
2312             // won't pass the "hasOuterInstance" check above, but those that don't have an
2313             // enclosing method (i.e. from initializers) will pass that check.
2314             boolean local = !currentOwner.owner.members().includes(currentOwner, LookupKind.NON_RECURSIVE);
2315             if (!currentOwner.name.isEmpty() && !local)
2316                 type = new MethodType(adjustMethodParams(flags, type.getParameterTypes()),
2317                                       type.getReturnType(),
2318                                       type.getThrownTypes(),
2319                                       syms.methodClass);
2320         }
2321         MethodSymbol m = new MethodSymbol(flags, name, type, currentOwner);
2322         if (types.isSignaturePolymorphic(m)) {
2323             m.flags_field |= SIGNATURE_POLYMORPHIC;
2324         }
2325         if (saveParameterNames)
2326             initParameterNames(m);
2327         Symbol prevOwner = currentOwner;

2332             currentOwner = prevOwner;
2333         }
2334         validateMethodType(name, m.type);
2335         setParameters(m, type);
2336 
2337         if (Integer.bitCount(rawFlags & (PUBLIC | PRIVATE | PROTECTED)) > 1)
2338             throw badClassFile("illegal.flag.combo", Flags.toString((long)rawFlags), "method", m);
2339         if ((flags & VARARGS) != 0) {
2340             final Type last = type.getParameterTypes().last();
2341             if (last == null || !last.hasTag(ARRAY)) {
2342                 m.flags_field &= ~VARARGS;
2343                 throw badClassFile("malformed.vararg.method", m);
2344             }
2345         }
2346 
2347         return m;
2348     }
2349 
2350     void validateMethodType(Name name, Type t) {
2351         if ((!t.hasTag(TypeTag.METHOD) && !t.hasTag(TypeTag.FORALL)) ||
2352             (name == names.init && !t.getReturnType().hasTag(TypeTag.VOID))) {
2353             throw badClassFile("method.descriptor.invalid", name);
2354         }
2355     }
2356 
2357     private List<Type> adjustMethodParams(long flags, List<Type> args) {
2358         if (args.isEmpty()) {
2359             return args;
2360         }
2361         boolean isVarargs = (flags & VARARGS) != 0;
2362         if (isVarargs) {
2363             Type varargsElem = args.last();
2364             ListBuffer<Type> adjustedArgs = new ListBuffer<>();
2365             for (Type t : args) {
2366                 adjustedArgs.append(t != varargsElem ?
2367                     t :
2368                     ((ArrayType)t).makeVarargs());
2369             }
2370             args = adjustedArgs.toList();
2371         }
2372         return args.tail;

2396 
2397     /**
2398      * Set the parameters for a method symbol, including any names and
2399      * annotations that were read.
2400      *
2401      * <p>The type of the symbol may have changed while reading the
2402      * method attributes (see the Signature attribute). This may be
2403      * because of generic information or because anonymous synthetic
2404      * parameters were added.   The original type (as read from the
2405      * method descriptor) is used to help guess the existence of
2406      * anonymous synthetic parameters.
2407      */
2408     void setParameters(MethodSymbol sym, Type jvmType) {
2409         int firstParamLvt = ((sym.flags() & STATIC) == 0) ? 1 : 0;
2410         // the code in readMethod may have skipped the first
2411         // parameter when setting up the MethodType. If so, we
2412         // make a corresponding allowance here for the position of
2413         // the first parameter.  Note that this assumes the
2414         // skipped parameter has a width of 1 -- i.e. it is not
2415         // a double width type (long or double.)
2416         if (sym.name == names.init && currentOwner.hasOuterInstance()) {
2417             // Sometimes anonymous classes don't have an outer
2418             // instance, however, there is no reliable way to tell so
2419             // we never strip this$n
2420             if (!currentOwner.name.isEmpty())
2421                 firstParamLvt += 1;
2422         }
2423 
2424         if (sym.type != jvmType) {
2425             // reading the method attributes has caused the
2426             // symbol's type to be changed. (i.e. the Signature
2427             // attribute.)  This may happen if there are hidden
2428             // (synthetic) parameters in the descriptor, but not
2429             // in the Signature.  The position of these hidden
2430             // parameters is unspecified; for now, assume they are
2431             // at the beginning, and so skip over them. The
2432             // primary case for this is two hidden parameters
2433             // passed into Enum constructors.
2434             int skip = Code.width(jvmType.getParameterTypes())
2435                     - Code.width(sym.type.getParameterTypes());
2436             firstParamLvt += skip;

2560         return syms.enterClass(currentModule, name, owner);
2561     }
2562 
2563     /** Read contents of a given class symbol `c'. Both external and internal
2564      *  versions of an inner class are read.
2565      */
2566     void readClass(ClassSymbol c) {
2567         ClassType ct = (ClassType)c.type;
2568 
2569         // allocate scope for members
2570         c.members_field = WriteableScope.create(c);
2571 
2572         // prepare type variable table
2573         typevars = typevars.dup(currentOwner);
2574         if (ct.getEnclosingType().hasTag(CLASS))
2575             enterTypevars(c.owner, ct.getEnclosingType());
2576 
2577         // read flags, or skip if this is an inner class
2578         long f = nextChar();
2579         long flags = adjustClassFlags(f);








2580         if ((flags & MODULE) == 0) {
2581             if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
2582             // read own class name and check that it matches
2583             currentModule = c.packge().modle;
2584             ClassSymbol self = poolReader.getClass(nextChar());
2585             if (c != self) {
2586                 throw badClassFile("class.file.wrong.class",
2587                                    self.flatname);
2588             }
2589         } else {
2590             if (majorVersion < Version.V53.major) {
2591                 throw badClassFile("anachronistic.module.info",
2592                         Integer.toString(majorVersion),
2593                         Integer.toString(minorVersion));
2594             }
2595             c.flags_field = flags;
2596             if (c.owner.kind != MDL) {
2597                 throw badClassFile("module.info.definition.expected");
2598             }
2599             currentModule = (ModuleSymbol) c.owner;

2817  * Adjusting flags
2818  ***********************************************************************/
2819 
2820     long adjustFieldFlags(long flags) {
2821         return flags;
2822     }
2823 
2824     long adjustMethodFlags(long flags) {
2825         if ((flags & ACC_BRIDGE) != 0) {
2826             flags &= ~ACC_BRIDGE;
2827             flags |= BRIDGE;
2828         }
2829         if ((flags & ACC_VARARGS) != 0) {
2830             flags &= ~ACC_VARARGS;
2831             flags |= VARARGS;
2832         }
2833         return flags;
2834     }
2835 
2836     long adjustClassFlags(long flags) {



2837         if ((flags & ACC_MODULE) != 0) {
2838             flags &= ~ACC_MODULE;
2839             flags |= MODULE;
2840         }
2841         return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
















2842     }
2843 
2844     /**
2845      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
2846      * The attribute is only the last component of the original filename, so is unlikely
2847      * to be valid as is, so operations other than those to access the name throw
2848      * UnsupportedOperationException
2849      */
2850     private static class SourceFileObject implements JavaFileObject {
2851 
2852         /** The file's name.
2853          */
2854         private final Name name;
2855 
2856         public SourceFileObject(Name name) {
2857             this.name = name;
2858         }
2859 
2860         @Override @DefinedBy(Api.COMPILER)
2861         public URI toUri() {

  28 import java.io.*;
  29 import java.net.URI;
  30 import java.net.URISyntaxException;
  31 import java.nio.CharBuffer;
  32 import java.nio.file.ClosedFileSystemException;
  33 import java.util.Arrays;
  34 import java.util.EnumSet;
  35 import java.util.HashMap;
  36 import java.util.HashSet;
  37 import java.util.Map;
  38 import java.util.Set;
  39 import java.util.function.IntFunction;
  40 
  41 import javax.lang.model.element.Modifier;
  42 import javax.lang.model.element.NestingKind;
  43 import javax.tools.JavaFileManager;
  44 import javax.tools.JavaFileObject;
  45 
  46 import com.sun.tools.javac.code.Source;
  47 import com.sun.tools.javac.code.Source.Feature;
  48 import com.sun.tools.javac.code.Type.ClassType.Flavor;
  49 import com.sun.tools.javac.comp.Annotate;
  50 import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
  51 import com.sun.tools.javac.code.*;
  52 import com.sun.tools.javac.code.Directive.*;
  53 import com.sun.tools.javac.code.Lint.LintCategory;
  54 import com.sun.tools.javac.code.Scope.WriteableScope;
  55 import com.sun.tools.javac.code.Symbol.*;
  56 import com.sun.tools.javac.code.Symtab;
  57 import com.sun.tools.javac.code.Type.*;
  58 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
  59 import com.sun.tools.javac.file.BaseFileManager;
  60 import com.sun.tools.javac.file.PathFileObject;
  61 import com.sun.tools.javac.jvm.ClassFile.Version;
  62 import com.sun.tools.javac.jvm.PoolConstant.NameAndType;
  63 import com.sun.tools.javac.main.Option;
  64 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  65 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  66 import com.sun.tools.javac.util.*;
  67 import com.sun.tools.javac.util.ByteBuffer.UnderflowException;
  68 import com.sun.tools.javac.util.DefinedBy.Api;

  92  *  If you write code that depends on this, you do so at your own risk.
  93  *  This code and its internal interfaces are subject to change or
  94  *  deletion without notice.</b>
  95  */
  96 public class ClassReader {
  97     /** The context key for the class reader. */
  98     protected static final Context.Key<ClassReader> classReaderKey = new Context.Key<>();
  99 
 100     public static final int INITIAL_BUFFER_SIZE = 0x0fff0;
 101 
 102     private final Annotate annotate;
 103 
 104     /** Switch: verbose output.
 105      */
 106     boolean verbose;
 107 
 108     /** Switch: allow modules.
 109      */
 110     boolean allowModules;
 111 
 112     /** Switch: allow primitive classes.
 113      */
 114     boolean allowPrimitiveClasses;
 115 
 116     /** Switch: allow value classes.
 117      */
 118     boolean allowValueClasses;
 119 
 120     /** Switch: allow sealed
 121      */
 122     boolean allowSealedTypes;
 123 
 124     /** Switch: allow records
 125      */
 126     boolean allowRecords;
 127 
 128    /** Lint option: warn about classfile issues
 129      */
 130     boolean lintClassfile;
 131 
 132     /** Switch: warn (instead of error) on illegal UTF-8
 133      */
 134     boolean warnOnIllegalUtf8;
 135 
 136     /** Switch: preserve parameter names from the variable table.
 137      */
 138     public boolean saveParameterNames;
 139 

 274     protected ClassReader(Context context) {
 275         context.put(classReaderKey, this);
 276         annotate = Annotate.instance(context);
 277         names = Names.instance(context);
 278         syms = Symtab.instance(context);
 279         types = Types.instance(context);
 280         fileManager = context.get(JavaFileManager.class);
 281         if (fileManager == null)
 282             throw new AssertionError("FileManager initialization error");
 283         diagFactory = JCDiagnostic.Factory.instance(context);
 284         dcfh = DeferredCompletionFailureHandler.instance(context);
 285 
 286         log = Log.instance(context);
 287 
 288         Options options = Options.instance(context);
 289         verbose         = options.isSet(Option.VERBOSE);
 290 
 291         Source source = Source.instance(context);
 292         preview = Preview.instance(context);
 293         allowModules     = Feature.MODULES.allowedInSource(source);
 294         allowPrimitiveClasses = Feature.PRIMITIVE_CLASSES.allowedInSource(source) && options.isSet("enablePrimitiveClasses");
 295         allowValueClasses = Feature.VALUE_CLASSES.allowedInSource(source);
 296         allowRecords = Feature.RECORDS.allowedInSource(source);
 297         allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
 298         warnOnIllegalUtf8 = Feature.WARN_ON_ILLEGAL_UTF8.allowedInSource(source);
 299 
 300         saveParameterNames = options.isSet(PARAMETERS);
 301 
 302         profile = Profile.instance(context);
 303 
 304         typevars = WriteableScope.create(syms.noSymbol);
 305 
 306         lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
 307 
 308         initAttributeReaders();
 309     }
 310 
 311     /** Add member to class unless it is synthetic.
 312      */
 313     private void enterMember(ClassSymbol c, Symbol sym) {
 314         // Synthetic members are not entered -- reason lost to history (optimization?).
 315         // Lambda methods must be entered because they may have inner classes (which reference them)

 494             return new WildcardType(t, BoundKind.SUPER, syms.boundClass);
 495         }
 496         case 'B':
 497             sigp++;
 498             return syms.byteType;
 499         case 'C':
 500             sigp++;
 501             return syms.charType;
 502         case 'D':
 503             sigp++;
 504             return syms.doubleType;
 505         case 'F':
 506             sigp++;
 507             return syms.floatType;
 508         case 'I':
 509             sigp++;
 510             return syms.intType;
 511         case 'J':
 512             sigp++;
 513             return syms.longType;
 514         case 'Q':
 515         case 'L':
 516             {
 517                 // int oldsigp = sigp;
 518                 if ((char) signature[sigp] == 'Q' && !allowPrimitiveClasses) {
 519                     throw badClassFile("bad.class.signature",
 520                                        quoteBadSignature());
 521                 }
 522                 Type t = classSigToType();
 523                 if (sigp < siglimit && signature[sigp] == '.')
 524                     throw badClassFile("deprecated inner class signature syntax " +
 525                                        "(please recompile from source)");
 526                 /*
 527                 System.err.println(" decoded " +
 528                                    new String(signature, oldsigp, sigp-oldsigp) +
 529                                    " => " + t + " outer " + t.outer());
 530                 */
 531                 return t;
 532             }
 533         case 'S':
 534             sigp++;
 535             return syms.shortType;
 536         case 'V':
 537             sigp++;
 538             return syms.voidType;
 539         case 'Z':
 540             sigp++;
 541             return syms.booleanType;

 559             }
 560             return new MethodType(argtypes,
 561                                   restype,
 562                                   thrown.reverse(),
 563                                   syms.methodClass);
 564         case '<':
 565             typevars = typevars.dup(currentOwner);
 566             Type poly = new ForAll(sigToTypeParams(), sigToType());
 567             typevars = typevars.leave();
 568             return poly;
 569         default:
 570             throw badClassFile("bad.signature", quoteBadSignature());
 571         }
 572     }
 573 
 574     byte[] signatureBuffer = new byte[0];
 575     int sbp = 0;
 576     /** Convert class signature to type, where signature is implicit.
 577      */
 578     Type classSigToType() {
 579         byte prefix = signature[sigp];
 580         if (prefix != 'L' && (!allowPrimitiveClasses || prefix != 'Q'))
 581             throw badClassFile("bad.class.signature", quoteBadSignature());
 582         sigp++;
 583         Type outer = Type.noType;
 584         Name name;
 585         ClassType.Flavor flavor;
 586         int startSbp = sbp;
 587 
 588         while (true) {
 589             final byte c = signature[sigp++];
 590             switch (c) {
 591 
 592             case ';': {         // end
 593                 ClassSymbol t = enterClass(readName(signatureBuffer,
 594                                                          startSbp,
 595                                                          sbp - startSbp));
 596 
 597                 // We are seeing QFoo; or LFoo; The name itself does not shine any light on default val-refness
 598                 flavor = prefix == 'L' ? Flavor.L_TypeOf_X : Flavor.Q_TypeOf_X;
 599                 try {
 600                     if (outer == Type.noType) {
 601                         ClassType et = (ClassType) t.erasure(types);
 602                         // Todo: This spews out more objects than before, i.e no reuse with identical flavor
 603                         return new ClassType(et.getEnclosingType(), List.nil(), et.tsym, et.getMetadata(), flavor);
 604                     }
 605                     return new ClassType(outer, List.nil(), t, List.nil(), flavor);
 606                 } finally {
 607                     sbp = startSbp;
 608                 }
 609             }
 610 
 611             case '<':           // generic arguments
 612                 ClassSymbol t = enterClass(readName(signatureBuffer,
 613                                                          startSbp,
 614                                                          sbp - startSbp));
 615                 // We are seeing QFoo; or LFoo; The name itself does not shine any light on default val-refness
 616                 flavor = prefix == 'L' ? Flavor.L_TypeOf_X : Flavor.Q_TypeOf_X;
 617                 outer = new ClassType(outer, sigToTypes('>'), t, List.nil(), flavor) {
 618                         boolean completed = false;
 619                         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 620                         public Type getEnclosingType() {
 621                             if (!completed) {
 622                                 completed = true;
 623                                 tsym.apiComplete();
 624                                 Type enclosingType = tsym.type.getEnclosingType();
 625                                 if (enclosingType != Type.noType) {
 626                                     List<Type> typeArgs =
 627                                         super.getEnclosingType().allparams();
 628                                     List<Type> typeParams =
 629                                         enclosingType.allparams();
 630                                     if (typeParams.length() != typeArgs.length()) {
 631                                         // no "rare" types
 632                                         super.setEnclosingType(types.erasure(enclosingType));
 633                                     } else {
 634                                         super.setEnclosingType(types.subst(enclosingType,
 635                                                                            typeParams,
 636                                                                            typeArgs));
 637                                     }

 660                         signatureBuffer[sbp++] = (byte)'$';
 661                         break;
 662                     } else {
 663                         sbp = startSbp;
 664                         return outer;
 665                     }
 666                 case '.':
 667                     signatureBuffer[sbp++] = (byte)'$';
 668                     break;
 669                 default:
 670                     throw new AssertionError(signature[sigp-1]);
 671                 }
 672                 continue;
 673 
 674             case '.':
 675                 //we have seen an enclosing non-generic class
 676                 if (outer != Type.noType) {
 677                     t = enterClass(readName(signatureBuffer,
 678                                                  startSbp,
 679                                                  sbp - startSbp));
 680                     // We are seeing QFoo; or LFoo; The name itself does not shine any light on default val-refness
 681                     flavor = prefix == 'L' ? Flavor.L_TypeOf_X : Flavor.Q_TypeOf_X;
 682                     outer = new ClassType(outer, List.nil(), t, List.nil(), flavor);
 683                 }
 684                 signatureBuffer[sbp++] = (byte)'$';
 685                 continue;
 686             case '/':
 687                 signatureBuffer[sbp++] = (byte)'.';
 688                 continue;
 689             default:
 690                 signatureBuffer[sbp++] = c;
 691                 continue;
 692             }
 693         }
 694     }
 695 
 696     /** Quote a bogus signature for display inside an error message.
 697      */
 698     String quoteBadSignature() {
 699         String sigString;
 700         try {
 701             sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
 702         } catch (InvalidUtfException e) {

 854         protected final Name name;
 855         protected final ClassFile.Version version;
 856         protected final Set<AttributeKind> kinds;
 857     }
 858 
 859     protected Set<AttributeKind> CLASS_ATTRIBUTE =
 860             EnumSet.of(AttributeKind.CLASS);
 861     protected Set<AttributeKind> MEMBER_ATTRIBUTE =
 862             EnumSet.of(AttributeKind.MEMBER);
 863     protected Set<AttributeKind> CLASS_OR_MEMBER_ATTRIBUTE =
 864             EnumSet.of(AttributeKind.CLASS, AttributeKind.MEMBER);
 865 
 866     protected Map<Name, AttributeReader> attributeReaders = new HashMap<>();
 867 
 868     private void initAttributeReaders() {
 869         AttributeReader[] readers = {
 870             // v45.3 attributes
 871 
 872             new AttributeReader(names.Code, V45_3, MEMBER_ATTRIBUTE) {
 873                 protected void read(Symbol sym, int attrLen) {
 874                     if (sym.isInitOrVNew() && sym.type.getParameterTypes().size() == 0) {
 875                         try {
 876                             int code_length = buf.getInt(bp + 4);
 877                             if ((code_length == 1 && buf.getByte(bp + 8) == (byte) ByteCodes.return_) ||
 878                                 (code_length == 5 && buf.getByte(bp + 8) == ByteCodes.aload_0 &&
 879                                     buf.getByte(bp + 9) == (byte) ByteCodes.invokespecial &&
 880                                             buf.getByte(bp + 12) == (byte) ByteCodes.return_)) {
 881                                 sym.flags_field |= EMPTYNOARGCONSTR;
 882                             }
 883                         } catch (UnderflowException e) {
 884                             throw badClassFile("bad.class.truncated.at.offset", Integer.toString(e.getLength()));
 885                         }
 886                     }
 887                     if (saveParameterNames)
 888                         ((MethodSymbol)sym).code = readCode(sym);
 889                     else
 890                         bp = bp + attrLen;
 891                 }
 892             },
 893 
 894             new AttributeReader(names.ConstantValue, V45_3, MEMBER_ATTRIBUTE) {
 895                 protected void read(Symbol sym, int attrLen) {
 896                     Object v = poolReader.getConstant(nextChar());
 897                     // Ignore ConstantValue attribute if field not final.
 898                     if ((sym.flags() & FINAL) == 0) {
 899                         return;
 900                     }
 901                     VarSymbol var = (VarSymbol) sym;
 902                     switch (var.type.getTag()) {
 903                        case BOOLEAN:
 904                        case BYTE:
 905                        case CHAR:
 906                        case SHORT:

1046                         ClassSymbol c = (ClassSymbol) sym;
1047                         readingClassAttr = true;
1048                         try {
1049                             ClassType ct1 = (ClassType)c.type;
1050                             Assert.check(c == currentOwner);
1051                             ct1.typarams_field = poolReader.getName(nextChar())
1052                                     .map(ClassReader.this::sigToTypeParams);
1053                             ct1.supertype_field = sigToType();
1054                             ListBuffer<Type> is = new ListBuffer<>();
1055                             while (sigp != siglimit) is.append(sigToType());
1056                             ct1.interfaces_field = is.toList();
1057                         } finally {
1058                             readingClassAttr = false;
1059                         }
1060                     } else {
1061                         List<Type> thrown = sym.type.getThrownTypes();
1062                         sym.type = poolReader.getType(nextChar());
1063                         //- System.err.println(" # " + sym.type);
1064                         if (sym.kind == MTH && sym.type.getThrownTypes().isEmpty())
1065                             sym.type.asMethodType().thrown = thrown;
1066                         // Map value class factory methods back to constructors for the benefit of earlier pipeline stages
1067                         if (sym.kind == MTH && sym.name == names.vnew && !sym.type.getReturnType().hasTag(TypeTag.VOID)) {
1068                             sym.type = new MethodType(sym.type.getParameterTypes(),
1069                                     syms.voidType,
1070                                     sym.type.getThrownTypes(),
1071                                     syms.methodClass);
1072                         }
1073 
1074                     }
1075                 }
1076             },
1077 
1078             // v49 annotation attributes
1079 
1080             new AttributeReader(names.AnnotationDefault, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
1081                 protected void read(Symbol sym, int attrLen) {
1082                     attachAnnotationDefault(sym);
1083                 }
1084             },
1085 
1086             new AttributeReader(names.RuntimeInvisibleAnnotations, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
1087                 protected void read(Symbol sym, int attrLen) {
1088                     attachAnnotations(sym);
1089                 }
1090             },
1091 
1092             new AttributeReader(names.RuntimeInvisibleParameterAnnotations, V49, CLASS_OR_MEMBER_ATTRIBUTE) {

1406         if (simpleBinaryName.length() < 1 || simpleBinaryName.charAt(0) != '$')
1407             throw badClassFile("bad.enclosing.method", self);
1408         int index = 1;
1409         while (index < simpleBinaryName.length() &&
1410                isAsciiDigit(simpleBinaryName.charAt(index)))
1411             index++;
1412         return names.fromString(simpleBinaryName.substring(index));
1413     }
1414 
1415     private MethodSymbol findMethod(NameAndType nt, Scope scope, long flags) {
1416         if (nt == null)
1417             return null;
1418 
1419         MethodType type = nt.type.asMethodType();
1420 
1421         for (Symbol sym : scope.getSymbolsByName(nt.name)) {
1422             if (sym.kind == MTH && isSameBinaryType(sym.type.asMethodType(), type))
1423                 return (MethodSymbol)sym;
1424         }
1425 
1426         if (!names.isInitOrVNew(nt.name))
1427             // not a constructor
1428             return null;
1429         if ((flags & INTERFACE) != 0)
1430             // no enclosing instance
1431             return null;
1432         if (nt.type.getParameterTypes().isEmpty())
1433             // no parameters
1434             return null;
1435 
1436         // A constructor of an inner class.
1437         // Remove the first argument (the enclosing instance)
1438         nt = new NameAndType(nt.name, new MethodType(nt.type.getParameterTypes().tail,
1439                                  nt.type.getReturnType(),
1440                                  nt.type.getThrownTypes(),
1441                                  syms.methodClass));
1442         // Try searching again
1443         return findMethod(nt, scope, flags);
1444     }
1445 
1446     /** Similar to Types.isSameType but avoids completion */

2334     MethodSymbol readMethod() {
2335         char rawFlags = nextChar();
2336         long flags = adjustMethodFlags(rawFlags);
2337         Name name = poolReader.getName(nextChar());
2338         Type type = poolReader.getType(nextChar());
2339         if (currentOwner.isInterface() &&
2340                 (flags & ABSTRACT) == 0 && !name.equals(names.clinit)) {
2341             if (majorVersion > Version.V52.major ||
2342                     (majorVersion == Version.V52.major && minorVersion >= Version.V52.minor)) {
2343                 if ((flags & (STATIC | PRIVATE)) == 0) {
2344                     currentOwner.flags_field |= DEFAULT;
2345                     flags |= DEFAULT | ABSTRACT;
2346                 }
2347             } else {
2348                 //protect against ill-formed classfiles
2349                 throw badClassFile((flags & STATIC) == 0 ? "invalid.default.interface" : "invalid.static.interface",
2350                                    Integer.toString(majorVersion),
2351                                    Integer.toString(minorVersion));
2352             }
2353         }
2354         if (names.isInitOrVNew(name) && ((flags & STATIC) != 0)) {
2355             flags &= ~STATIC;
2356             type = new MethodType(type.getParameterTypes(),
2357                     syms.voidType,
2358                     type.getThrownTypes(),
2359                     syms.methodClass);
2360         }
2361         validateMethodType(name, type);
2362         if (names.isInitOrVNew(name) && currentOwner.hasOuterInstance()) {
2363             // Sometimes anonymous classes don't have an outer
2364             // instance, however, there is no reliable way to tell so
2365             // we never strip this$n
2366             // ditto for local classes. Local classes that have an enclosing method set
2367             // won't pass the "hasOuterInstance" check above, but those that don't have an
2368             // enclosing method (i.e. from initializers) will pass that check.
2369             boolean local = !currentOwner.owner.members().includes(currentOwner, LookupKind.NON_RECURSIVE);
2370             if (!currentOwner.name.isEmpty() && !local)
2371                 type = new MethodType(adjustMethodParams(flags, type.getParameterTypes()),
2372                                       type.getReturnType(),
2373                                       type.getThrownTypes(),
2374                                       syms.methodClass);
2375         }
2376         MethodSymbol m = new MethodSymbol(flags, name, type, currentOwner);
2377         if (types.isSignaturePolymorphic(m)) {
2378             m.flags_field |= SIGNATURE_POLYMORPHIC;
2379         }
2380         if (saveParameterNames)
2381             initParameterNames(m);
2382         Symbol prevOwner = currentOwner;

2387             currentOwner = prevOwner;
2388         }
2389         validateMethodType(name, m.type);
2390         setParameters(m, type);
2391 
2392         if (Integer.bitCount(rawFlags & (PUBLIC | PRIVATE | PROTECTED)) > 1)
2393             throw badClassFile("illegal.flag.combo", Flags.toString((long)rawFlags), "method", m);
2394         if ((flags & VARARGS) != 0) {
2395             final Type last = type.getParameterTypes().last();
2396             if (last == null || !last.hasTag(ARRAY)) {
2397                 m.flags_field &= ~VARARGS;
2398                 throw badClassFile("malformed.vararg.method", m);
2399             }
2400         }
2401 
2402         return m;
2403     }
2404 
2405     void validateMethodType(Name name, Type t) {
2406         if ((!t.hasTag(TypeTag.METHOD) && !t.hasTag(TypeTag.FORALL)) ||
2407             ((name == names.init || name == names.vnew) && !t.getReturnType().hasTag(TypeTag.VOID))) {
2408             throw badClassFile("method.descriptor.invalid", name);
2409         }
2410     }
2411 
2412     private List<Type> adjustMethodParams(long flags, List<Type> args) {
2413         if (args.isEmpty()) {
2414             return args;
2415         }
2416         boolean isVarargs = (flags & VARARGS) != 0;
2417         if (isVarargs) {
2418             Type varargsElem = args.last();
2419             ListBuffer<Type> adjustedArgs = new ListBuffer<>();
2420             for (Type t : args) {
2421                 adjustedArgs.append(t != varargsElem ?
2422                     t :
2423                     ((ArrayType)t).makeVarargs());
2424             }
2425             args = adjustedArgs.toList();
2426         }
2427         return args.tail;

2451 
2452     /**
2453      * Set the parameters for a method symbol, including any names and
2454      * annotations that were read.
2455      *
2456      * <p>The type of the symbol may have changed while reading the
2457      * method attributes (see the Signature attribute). This may be
2458      * because of generic information or because anonymous synthetic
2459      * parameters were added.   The original type (as read from the
2460      * method descriptor) is used to help guess the existence of
2461      * anonymous synthetic parameters.
2462      */
2463     void setParameters(MethodSymbol sym, Type jvmType) {
2464         int firstParamLvt = ((sym.flags() & STATIC) == 0) ? 1 : 0;
2465         // the code in readMethod may have skipped the first
2466         // parameter when setting up the MethodType. If so, we
2467         // make a corresponding allowance here for the position of
2468         // the first parameter.  Note that this assumes the
2469         // skipped parameter has a width of 1 -- i.e. it is not
2470         // a double width type (long or double.)
2471         if (names.isInitOrVNew(sym.name) && currentOwner.hasOuterInstance()) {
2472             // Sometimes anonymous classes don't have an outer
2473             // instance, however, there is no reliable way to tell so
2474             // we never strip this$n
2475             if (!currentOwner.name.isEmpty())
2476                 firstParamLvt += 1;
2477         }
2478 
2479         if (sym.type != jvmType) {
2480             // reading the method attributes has caused the
2481             // symbol's type to be changed. (i.e. the Signature
2482             // attribute.)  This may happen if there are hidden
2483             // (synthetic) parameters in the descriptor, but not
2484             // in the Signature.  The position of these hidden
2485             // parameters is unspecified; for now, assume they are
2486             // at the beginning, and so skip over them. The
2487             // primary case for this is two hidden parameters
2488             // passed into Enum constructors.
2489             int skip = Code.width(jvmType.getParameterTypes())
2490                     - Code.width(sym.type.getParameterTypes());
2491             firstParamLvt += skip;

2615         return syms.enterClass(currentModule, name, owner);
2616     }
2617 
2618     /** Read contents of a given class symbol `c'. Both external and internal
2619      *  versions of an inner class are read.
2620      */
2621     void readClass(ClassSymbol c) {
2622         ClassType ct = (ClassType)c.type;
2623 
2624         // allocate scope for members
2625         c.members_field = WriteableScope.create(c);
2626 
2627         // prepare type variable table
2628         typevars = typevars.dup(currentOwner);
2629         if (ct.getEnclosingType().hasTag(CLASS))
2630             enterTypevars(c.owner, ct.getEnclosingType());
2631 
2632         // read flags, or skip if this is an inner class
2633         long f = nextChar();
2634         long flags = adjustClassFlags(f);
2635         if (c == syms.objectType.tsym) {
2636             flags &= ~IDENTITY_TYPE; // jlO lacks identity even while being a concrete class.
2637         }
2638         if ((flags & PRIMITIVE_CLASS) != 0) {
2639             if (!allowPrimitiveClasses || (flags & (FINAL | PRIMITIVE_CLASS | IDENTITY_TYPE)) != (FINAL | PRIMITIVE_CLASS)) {
2640                 throw badClassFile("bad.access.flags", Flags.toString(flags));
2641             }
2642         }
2643         if ((flags & MODULE) == 0) {
2644             if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
2645             // read own class name and check that it matches
2646             currentModule = c.packge().modle;
2647             ClassSymbol self = poolReader.getClass(nextChar());
2648             if (c != self) {
2649                 throw badClassFile("class.file.wrong.class",
2650                                    self.flatname);
2651             }
2652         } else {
2653             if (majorVersion < Version.V53.major) {
2654                 throw badClassFile("anachronistic.module.info",
2655                         Integer.toString(majorVersion),
2656                         Integer.toString(minorVersion));
2657             }
2658             c.flags_field = flags;
2659             if (c.owner.kind != MDL) {
2660                 throw badClassFile("module.info.definition.expected");
2661             }
2662             currentModule = (ModuleSymbol) c.owner;

2880  * Adjusting flags
2881  ***********************************************************************/
2882 
2883     long adjustFieldFlags(long flags) {
2884         return flags;
2885     }
2886 
2887     long adjustMethodFlags(long flags) {
2888         if ((flags & ACC_BRIDGE) != 0) {
2889             flags &= ~ACC_BRIDGE;
2890             flags |= BRIDGE;
2891         }
2892         if ((flags & ACC_VARARGS) != 0) {
2893             flags &= ~ACC_VARARGS;
2894             flags |= VARARGS;
2895         }
2896         return flags;
2897     }
2898 
2899     long adjustClassFlags(long flags) {
2900         if ((flags & (ABSTRACT | INTERFACE | ACC_VALUE | ACC_MODULE)) == 0) {
2901             flags |= ACC_IDENTITY;
2902         }
2903         if ((flags & ACC_MODULE) != 0) {
2904             flags &= ~ACC_MODULE;
2905             flags |= MODULE;
2906         }
2907         if ((flags & ACC_PRIMITIVE) != 0) {
2908             flags &= ~ACC_PRIMITIVE;
2909             if (allowPrimitiveClasses) {
2910                 flags |= PRIMITIVE_CLASS;
2911             }
2912         }
2913         if ((flags & ACC_VALUE) != 0) {
2914             flags &= ~ACC_VALUE;
2915             if (allowValueClasses) {
2916                 flags |= VALUE_CLASS;
2917             }
2918         }
2919         if ((flags & ACC_IDENTITY) != 0) {
2920             flags &= ~ACC_IDENTITY;
2921             flags |= IDENTITY_TYPE;
2922         }
2923         return flags;
2924     }
2925 
2926     /**
2927      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
2928      * The attribute is only the last component of the original filename, so is unlikely
2929      * to be valid as is, so operations other than those to access the name throw
2930      * UnsupportedOperationException
2931      */
2932     private static class SourceFileObject implements JavaFileObject {
2933 
2934         /** The file's name.
2935          */
2936         private final Name name;
2937 
2938         public SourceFileObject(Name name) {
2939             this.name = name;
2940         }
2941 
2942         @Override @DefinedBy(Api.COMPILER)
2943         public URI toUri() {
< prev index next >