< prev index next >

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

Print this page




  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.jvm;
  27 
  28 import java.io.*;
  29 import java.net.URI;
  30 import java.net.URISyntaxException;
  31 import java.nio.CharBuffer;
  32 import java.nio.file.Path;
  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 
  40 import javax.tools.JavaFileManager;
  41 import javax.tools.JavaFileObject;
  42 

  43 import com.sun.tools.javac.code.*;
  44 import com.sun.tools.javac.code.Lint.LintCategory;
  45 import com.sun.tools.javac.code.Scope.WriteableScope;
  46 import com.sun.tools.javac.code.Symbol.*;
  47 import com.sun.tools.javac.code.Symtab;
  48 import com.sun.tools.javac.code.Type.*;
  49 import com.sun.tools.javac.comp.Annotate;
  50 import com.sun.tools.javac.file.BaseFileObject;
  51 import com.sun.tools.javac.jvm.ClassFile.NameAndType;
  52 import com.sun.tools.javac.jvm.ClassFile.Version;
  53 import com.sun.tools.javac.util.*;
  54 import com.sun.tools.javac.util.DefinedBy.Api;
  55 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  56 
  57 import static com.sun.tools.javac.code.Flags.*;
  58 import static com.sun.tools.javac.code.Kinds.Kind.*;
  59 import static com.sun.tools.javac.code.TypeTag.CLASS;
  60 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
  61 import static com.sun.tools.javac.jvm.ClassFile.*;
  62 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
  63 
  64 import static com.sun.tools.javac.main.Option.*;
  65 
  66 /** This class provides operations to read a classfile into an internal
  67  *  representation. The internal representation is anchored in a
  68  *  ClassSymbol which contains in its scope symbol representations
  69  *  for all other definitions in the classfile. Top-level Classes themselves
  70  *  appear as members of the scopes of PackageSymbols.
  71  *
  72  *  <p><b>This is NOT part of any supported API.
  73  *  If you write code that depends on this, you do so at your own risk.
  74  *  This code and its internal interfaces are subject to change or
  75  *  deletion without notice.</b>
  76  */
  77 public class ClassReader {
  78     /** The context key for the class reader. */
  79     protected static final Context.Key<ClassReader> classReaderKey = new Context.Key<>();
  80 
  81     public static final int INITIAL_BUFFER_SIZE = 0x0fff0;
  82 
  83     Annotate annotate;
  84 
  85     /** Switch: verbose output.
  86      */
  87     boolean verbose;
  88 
  89     /** Switch: check class file for correct minor version, unrecognized
  90      *  attributes.
  91      */
  92     boolean checkClassFile;
  93 
  94     /** Switch: read constant pool and code sections. This switch is initially
  95      *  set to false but can be turned on from outside.
  96      */
  97     public boolean readAllOfClassFile = false;
  98 
  99     /** Switch: allow simplified varargs.
 100      */
 101     boolean allowSimplifiedVarargs;
 102 
 103    /** Lint option: warn about classfile issues


 172      */
 173     int[] parameterNameIndices;
 174 
 175     /**
 176      * Whether or not any parameter names have been found.
 177      */
 178     boolean haveParameterNameIndices;
 179 
 180     /** Set this to false every time we start reading a method
 181      * and are saving parameter names.  Set it to true when we see
 182      * MethodParameters, if it's set when we see a LocalVariableTable,
 183      * then we ignore the parameter names from the LVT.
 184      */
 185     boolean sawMethodParameters;
 186 
 187     /**
 188      * The set of attribute names for which warnings have been generated for the current class
 189      */
 190     Set<Name> warnedAttrs = new HashSet<>();
 191 












 192     /** Get the ClassReader instance for this invocation. */
 193     public static ClassReader instance(Context context) {
 194         ClassReader instance = context.get(classReaderKey);
 195         if (instance == null)
 196             instance = new ClassReader(context);
 197         return instance;
 198     }
 199 
 200     /** Construct a new class reader. */
 201     protected ClassReader(Context context) {
 202         context.put(classReaderKey, this);

 203         names = Names.instance(context);
 204         syms = Symtab.instance(context);
 205         types = Types.instance(context);
 206         fileManager = context.get(JavaFileManager.class);
 207         if (fileManager == null)
 208             throw new AssertionError("FileManager initialization error");
 209         diagFactory = JCDiagnostic.Factory.instance(context);
 210 
 211         log = Log.instance(context);
 212 
 213         Options options = Options.instance(context);
 214         annotate = Annotate.instance(context);
 215         verbose        = options.isSet(VERBOSE);
 216         checkClassFile = options.isSet("-checkclassfile");
 217 
 218         Source source = Source.instance(context);
 219         allowSimplifiedVarargs = source.allowSimplifiedVarargs();
 220 
 221         saveParameterNames = options.isSet("save-parameter-names");
 222 
 223         profile = Profile.instance(context);
 224 
 225         typevars = WriteableScope.create(syms.noSymbol);
 226 
 227         lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
 228 
 229         initAttributeReaders();
 230     }
 231 
 232     /** Add member to class unless it is synthetic.
 233      */
 234     private void enterMember(ClassSymbol c, Symbol sym) {


1286         final int  code_length = nextInt();
1287         bp += code_length;
1288         final char exception_table_length = nextChar();
1289         bp += exception_table_length * 8;
1290         readMemberAttrs(owner);
1291         return null;
1292     }
1293 
1294 /************************************************************************
1295  * Reading Java-language annotations
1296  ***********************************************************************/
1297 
1298     /** Attach annotations.
1299      */
1300     void attachAnnotations(final Symbol sym) {
1301         int numAttributes = nextChar();
1302         if (numAttributes != 0) {
1303             ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1304             for (int i = 0; i<numAttributes; i++) {
1305                 CompoundAnnotationProxy proxy = readCompoundAnnotation();







1306                 proxies.append(proxy);
1307             }
1308             annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1309         }
1310     }
1311 
1312     /** Attach parameter annotations.
1313      */
1314     void attachParameterAnnotations(final Symbol method) {
1315         final MethodSymbol meth = (MethodSymbol)method;
1316         int numParameters = buf[bp++] & 0xFF;
1317         List<VarSymbol> parameters = meth.params();
1318         int pnum = 0;
1319         while (parameters.tail != null) {
1320             attachAnnotations(parameters.head);
1321             parameters = parameters.tail;
1322             pnum++;
1323         }
1324         if (pnum != numParameters) {
1325             throw badClassFile("bad.runtime.invisible.param.annotations", meth);


1687                 buf.append(value.snd);
1688             }
1689             buf.append("}");
1690             return buf.toString();
1691         }
1692     }
1693 
1694     /** A temporary proxy representing a type annotation.
1695      */
1696     static class TypeAnnotationProxy {
1697         final CompoundAnnotationProxy compound;
1698         final TypeAnnotationPosition position;
1699         public TypeAnnotationProxy(CompoundAnnotationProxy compound,
1700                 TypeAnnotationPosition position) {
1701             this.compound = compound;
1702             this.position = position;
1703         }
1704     }
1705 
1706     class AnnotationDeproxy implements ProxyVisitor {
1707         private ClassSymbol requestingOwner = currentOwner.kind == MTH
1708             ? currentOwner.enclClass() : (ClassSymbol)currentOwner;



1709 
1710         List<Attribute.Compound> deproxyCompoundList(List<CompoundAnnotationProxy> pl) {
1711             // also must fill in types!!!!
1712             ListBuffer<Attribute.Compound> buf = new ListBuffer<>();
1713             for (List<CompoundAnnotationProxy> l = pl; l.nonEmpty(); l=l.tail) {
1714                 buf.append(deproxyCompound(l.head));
1715             }
1716             return buf.toList();
1717         }
1718 
1719         Attribute.Compound deproxyCompound(CompoundAnnotationProxy a) {
1720             ListBuffer<Pair<Symbol.MethodSymbol,Attribute>> buf = new ListBuffer<>();
1721             for (List<Pair<Name,Attribute>> l = a.values;
1722                  l.nonEmpty();
1723                  l = l.tail) {
1724                 MethodSymbol meth = findAccessMethod(a.type, l.head.fst);
1725                 buf.append(new Pair<>(meth, deproxy(meth.type.getReturnType(), l.head.snd)));
1726             }
1727             return new Attribute.Compound(a.type, buf.toList());
1728         }


1837                 result = new Attribute.Enum(enumTypeSym.type, enumerator);
1838             }
1839         }
1840 
1841         public void visitArrayAttributeProxy(ArrayAttributeProxy proxy) {
1842             int length = proxy.values.length();
1843             Attribute[] ats = new Attribute[length];
1844             Type elemtype = types.elemtype(type);
1845             int i = 0;
1846             for (List<Attribute> p = proxy.values; p.nonEmpty(); p = p.tail) {
1847                 ats[i++] = deproxy(elemtype, p.head);
1848             }
1849             result = new Attribute.Array(type, ats);
1850         }
1851 
1852         public void visitCompoundAnnotationProxy(CompoundAnnotationProxy proxy) {
1853             result = deproxyCompound(proxy);
1854         }
1855     }
1856 
1857     class AnnotationDefaultCompleter extends AnnotationDeproxy implements Annotate.Worker {
1858         final MethodSymbol sym;
1859         final Attribute value;
1860         final JavaFileObject classFile = currentClassFile;
1861         @Override
1862         public String toString() {
1863             return " ClassReader store default for " + sym.owner + "." + sym + " is " + value;
1864         }
1865         AnnotationDefaultCompleter(MethodSymbol sym, Attribute value) {


1866             this.sym = sym;
1867             this.value = value;
1868         }
1869         // implement Annotate.Worker.run()

1870         public void run() {
1871             JavaFileObject previousClassFile = currentClassFile;
1872             try {
1873                 // Reset the interim value set earlier in
1874                 // attachAnnotationDefault().
1875                 sym.defaultValue = null;
1876                 currentClassFile = classFile;
1877                 sym.defaultValue = deproxy(sym.type.getReturnType(), value);
1878             } finally {
1879                 currentClassFile = previousClassFile;
1880             }
1881         }





1882     }
1883 
1884     class AnnotationCompleter extends AnnotationDeproxy implements Annotate.Worker {
1885         final Symbol sym;
1886         final List<CompoundAnnotationProxy> l;
1887         final JavaFileObject classFile;
1888         @Override
1889         public String toString() {
1890             return " ClassReader annotate " + sym.owner + "." + sym + " with " + l;
1891         }
1892         AnnotationCompleter(Symbol sym, List<CompoundAnnotationProxy> l) {


1893             this.sym = sym;
1894             this.l = l;
1895             this.classFile = currentClassFile;
1896         }
1897         // implement Annotate.Worker.run()

1898         public void run() {
1899             JavaFileObject previousClassFile = currentClassFile;
1900             try {
1901                 currentClassFile = classFile;
1902                 List<Attribute.Compound> newList = deproxyCompoundList(l);
1903                 if (sym.annotationsPendingCompletion()) {
1904                     sym.setDeclarationAttributes(newList);
1905                 } else {
1906                     sym.appendAttributes(newList);
1907                 }
1908             } finally {
1909                 currentClassFile = previousClassFile;
1910             }
1911         }





1912     }
1913 
1914     class TypeAnnotationCompleter extends AnnotationCompleter {
1915 
1916         List<TypeAnnotationProxy> proxies;
1917 
1918         TypeAnnotationCompleter(Symbol sym,
1919                 List<TypeAnnotationProxy> proxies) {
1920             super(sym, List.<CompoundAnnotationProxy>nil());
1921             this.proxies = proxies;
1922         }
1923 
1924         List<Attribute.TypeCompound> deproxyTypeCompoundList(List<TypeAnnotationProxy> proxies) {
1925             ListBuffer<Attribute.TypeCompound> buf = new ListBuffer<>();
1926             for (TypeAnnotationProxy proxy: proxies) {
1927                 Attribute.Compound compound = deproxyCompound(proxy.compound);
1928                 Attribute.TypeCompound typeCompound = new Attribute.TypeCompound(compound, proxy.position);
1929                 buf.add(typeCompound);
1930             }
1931             return buf.toList();


2271         else if (checkClassFile &&
2272                  majorVersion == maxMajor &&
2273                  minorVersion > maxMinor)
2274         {
2275             printCCF("found.later.version",
2276                      Integer.toString(minorVersion));
2277         }
2278         indexPool();
2279         if (signatureBuffer.length < bp) {
2280             int ns = Integer.highestOneBit(bp) << 1;
2281             signatureBuffer = new byte[ns];
2282         }
2283         readClass(c);
2284     }
2285 
2286     public void readClassFile(ClassSymbol c) {
2287         currentOwner = c;
2288         currentClassFile = c.classfile;
2289         warnedAttrs.clear();
2290         filling = true;


2291         try {
2292             bp = 0;
2293             buf = readInputStream(buf, c.classfile.openInputStream());
2294             readClassBuffer(c);
2295             if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) {
2296                 List<Type> missing = missingTypeVariables;
2297                 List<Type> found = foundTypeVariables;
2298                 missingTypeVariables = List.nil();
2299                 foundTypeVariables = List.nil();
2300                 filling = false;
2301                 ClassType ct = (ClassType)currentOwner.type;
2302                 ct.supertype_field =
2303                     types.subst(ct.supertype_field, missing, found);
2304                 ct.interfaces_field =
2305                     types.subst(ct.interfaces_field, missing, found);
2306             } else if (missingTypeVariables.isEmpty() !=
2307                        foundTypeVariables.isEmpty()) {
2308                 Name name = missingTypeVariables.head.tsym.name;
2309                 throw badClassFile("undecl.type.var", name);
2310             }






2311         } catch (IOException ex) {
2312             throw badClassFile("unable.to.access.file", ex.getMessage());
2313         } catch (ArrayIndexOutOfBoundsException ex) {
2314             throw badClassFile("bad.class.file", c.flatname);
2315         } finally {
2316             missingTypeVariables = List.nil();
2317             foundTypeVariables = List.nil();
2318             filling = false;
2319         }
2320     }
2321     // where
2322         private static byte[] readInputStream(byte[] buf, InputStream s) throws IOException {
2323             try {
2324                 buf = ensureCapacity(buf, s.available());
2325                 int r = s.read(buf);
2326                 int bp = 0;
2327                 while (r != -1) {
2328                     bp += r;
2329                     buf = ensureCapacity(buf, bp);
2330                     r = s.read(buf, bp, buf.length - bp);


2488          * SourceFile attribute, and do not directly represent specific files.
2489          * Two SourceFileObjects are equal if their names are equal.
2490          */
2491         @Override
2492         public boolean equals(Object other) {
2493             if (this == other)
2494                 return true;
2495 
2496             if (!(other instanceof SourceFileObject))
2497                 return false;
2498 
2499             SourceFileObject o = (SourceFileObject) other;
2500             return name.equals(o.name);
2501         }
2502 
2503         @Override
2504         public int hashCode() {
2505             return name.hashCode();
2506         }
2507     }






































2508 }


  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.jvm;
  27 
  28 import java.io.*;
  29 import java.net.URI;
  30 import java.net.URISyntaxException;
  31 import java.nio.CharBuffer;
  32 import java.nio.file.Path;
  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 javax.tools.JavaFileManager;
  40 import javax.tools.JavaFileObject;
  41 import com.sun.tools.javac.comp.Annotate;
  42 import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
  43 import com.sun.tools.javac.code.*;
  44 import com.sun.tools.javac.code.Lint.LintCategory;
  45 import com.sun.tools.javac.code.Scope.WriteableScope;
  46 import com.sun.tools.javac.code.Symbol.*;
  47 import com.sun.tools.javac.code.Symtab;
  48 import com.sun.tools.javac.code.Type.*;
  49 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
  50 import com.sun.tools.javac.file.BaseFileObject;
  51 import com.sun.tools.javac.jvm.ClassFile.NameAndType;
  52 import com.sun.tools.javac.jvm.ClassFile.Version;
  53 import com.sun.tools.javac.util.*;
  54 import com.sun.tools.javac.util.DefinedBy.Api;
  55 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  56 
  57 import static com.sun.tools.javac.code.Flags.*;
  58 import static com.sun.tools.javac.code.Kinds.Kind.*;
  59 import static com.sun.tools.javac.code.TypeTag.CLASS;
  60 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
  61 import static com.sun.tools.javac.jvm.ClassFile.*;
  62 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
  63 
  64 import static com.sun.tools.javac.main.Option.*;
  65 
  66 /** This class provides operations to read a classfile into an internal
  67  *  representation. The internal representation is anchored in a
  68  *  ClassSymbol which contains in its scope symbol representations
  69  *  for all other definitions in the classfile. Top-level Classes themselves
  70  *  appear as members of the scopes of PackageSymbols.
  71  *
  72  *  <p><b>This is NOT part of any supported API.
  73  *  If you write code that depends on this, you do so at your own risk.
  74  *  This code and its internal interfaces are subject to change or
  75  *  deletion without notice.</b>
  76  */
  77 public class ClassReader {
  78     /** The context key for the class reader. */
  79     protected static final Context.Key<ClassReader> classReaderKey = new Context.Key<>();
  80 
  81     public static final int INITIAL_BUFFER_SIZE = 0x0fff0;
  82 
  83     private final Annotate annotate;
  84 
  85     /** Switch: verbose output.
  86      */
  87     boolean verbose;
  88 
  89     /** Switch: check class file for correct minor version, unrecognized
  90      *  attributes.
  91      */
  92     boolean checkClassFile;
  93 
  94     /** Switch: read constant pool and code sections. This switch is initially
  95      *  set to false but can be turned on from outside.
  96      */
  97     public boolean readAllOfClassFile = false;
  98 
  99     /** Switch: allow simplified varargs.
 100      */
 101     boolean allowSimplifiedVarargs;
 102 
 103    /** Lint option: warn about classfile issues


 172      */
 173     int[] parameterNameIndices;
 174 
 175     /**
 176      * Whether or not any parameter names have been found.
 177      */
 178     boolean haveParameterNameIndices;
 179 
 180     /** Set this to false every time we start reading a method
 181      * and are saving parameter names.  Set it to true when we see
 182      * MethodParameters, if it's set when we see a LocalVariableTable,
 183      * then we ignore the parameter names from the LVT.
 184      */
 185     boolean sawMethodParameters;
 186 
 187     /**
 188      * The set of attribute names for which warnings have been generated for the current class
 189      */
 190     Set<Name> warnedAttrs = new HashSet<>();
 191 
 192     /**
 193      * The prototype @Target Attribute.Compound if this class is an annotation annotated with
 194      * @Target
 195      */
 196     CompoundAnnotationProxy target;
 197 
 198     /**
 199      * The prototype @Repetable Attribute.Compound if this class is an annotation annotated with
 200      * @Repeatable
 201      */
 202     CompoundAnnotationProxy repeatable;
 203 
 204     /** Get the ClassReader instance for this invocation. */
 205     public static ClassReader instance(Context context) {
 206         ClassReader instance = context.get(classReaderKey);
 207         if (instance == null)
 208             instance = new ClassReader(context);
 209         return instance;
 210     }
 211 
 212     /** Construct a new class reader. */
 213     protected ClassReader(Context context) {
 214         context.put(classReaderKey, this);
 215         annotate = Annotate.instance(context);
 216         names = Names.instance(context);
 217         syms = Symtab.instance(context);
 218         types = Types.instance(context);
 219         fileManager = context.get(JavaFileManager.class);
 220         if (fileManager == null)
 221             throw new AssertionError("FileManager initialization error");
 222         diagFactory = JCDiagnostic.Factory.instance(context);
 223 
 224         log = Log.instance(context);
 225 
 226         Options options = Options.instance(context);

 227         verbose         = options.isSet(VERBOSE);
 228         checkClassFile  = options.isSet("-checkclassfile");
 229 
 230         Source source = Source.instance(context);
 231         allowSimplifiedVarargs = source.allowSimplifiedVarargs();
 232 
 233         saveParameterNames = options.isSet("save-parameter-names");
 234 
 235         profile = Profile.instance(context);
 236 
 237         typevars = WriteableScope.create(syms.noSymbol);
 238 
 239         lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
 240 
 241         initAttributeReaders();
 242     }
 243 
 244     /** Add member to class unless it is synthetic.
 245      */
 246     private void enterMember(ClassSymbol c, Symbol sym) {


1298         final int  code_length = nextInt();
1299         bp += code_length;
1300         final char exception_table_length = nextChar();
1301         bp += exception_table_length * 8;
1302         readMemberAttrs(owner);
1303         return null;
1304     }
1305 
1306 /************************************************************************
1307  * Reading Java-language annotations
1308  ***********************************************************************/
1309 
1310     /** Attach annotations.
1311      */
1312     void attachAnnotations(final Symbol sym) {
1313         int numAttributes = nextChar();
1314         if (numAttributes != 0) {
1315             ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1316             for (int i = 0; i<numAttributes; i++) {
1317                 CompoundAnnotationProxy proxy = readCompoundAnnotation();
1318 
1319                 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1320                     target = proxy;
1321                 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1322                     repeatable = proxy;
1323                 }
1324 
1325                 proxies.append(proxy);
1326             }
1327             annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1328         }
1329     }
1330 
1331     /** Attach parameter annotations.
1332      */
1333     void attachParameterAnnotations(final Symbol method) {
1334         final MethodSymbol meth = (MethodSymbol)method;
1335         int numParameters = buf[bp++] & 0xFF;
1336         List<VarSymbol> parameters = meth.params();
1337         int pnum = 0;
1338         while (parameters.tail != null) {
1339             attachAnnotations(parameters.head);
1340             parameters = parameters.tail;
1341             pnum++;
1342         }
1343         if (pnum != numParameters) {
1344             throw badClassFile("bad.runtime.invisible.param.annotations", meth);


1706                 buf.append(value.snd);
1707             }
1708             buf.append("}");
1709             return buf.toString();
1710         }
1711     }
1712 
1713     /** A temporary proxy representing a type annotation.
1714      */
1715     static class TypeAnnotationProxy {
1716         final CompoundAnnotationProxy compound;
1717         final TypeAnnotationPosition position;
1718         public TypeAnnotationProxy(CompoundAnnotationProxy compound,
1719                 TypeAnnotationPosition position) {
1720             this.compound = compound;
1721             this.position = position;
1722         }
1723     }
1724 
1725     class AnnotationDeproxy implements ProxyVisitor {
1726         private ClassSymbol requestingOwner;
1727 
1728         AnnotationDeproxy(ClassSymbol owner) {
1729             this.requestingOwner = owner;
1730         }
1731 
1732         List<Attribute.Compound> deproxyCompoundList(List<CompoundAnnotationProxy> pl) {
1733             // also must fill in types!!!!
1734             ListBuffer<Attribute.Compound> buf = new ListBuffer<>();
1735             for (List<CompoundAnnotationProxy> l = pl; l.nonEmpty(); l=l.tail) {
1736                 buf.append(deproxyCompound(l.head));
1737             }
1738             return buf.toList();
1739         }
1740 
1741         Attribute.Compound deproxyCompound(CompoundAnnotationProxy a) {
1742             ListBuffer<Pair<Symbol.MethodSymbol,Attribute>> buf = new ListBuffer<>();
1743             for (List<Pair<Name,Attribute>> l = a.values;
1744                  l.nonEmpty();
1745                  l = l.tail) {
1746                 MethodSymbol meth = findAccessMethod(a.type, l.head.fst);
1747                 buf.append(new Pair<>(meth, deproxy(meth.type.getReturnType(), l.head.snd)));
1748             }
1749             return new Attribute.Compound(a.type, buf.toList());
1750         }


1859                 result = new Attribute.Enum(enumTypeSym.type, enumerator);
1860             }
1861         }
1862 
1863         public void visitArrayAttributeProxy(ArrayAttributeProxy proxy) {
1864             int length = proxy.values.length();
1865             Attribute[] ats = new Attribute[length];
1866             Type elemtype = types.elemtype(type);
1867             int i = 0;
1868             for (List<Attribute> p = proxy.values; p.nonEmpty(); p = p.tail) {
1869                 ats[i++] = deproxy(elemtype, p.head);
1870             }
1871             result = new Attribute.Array(type, ats);
1872         }
1873 
1874         public void visitCompoundAnnotationProxy(CompoundAnnotationProxy proxy) {
1875             result = deproxyCompound(proxy);
1876         }
1877     }
1878 
1879     class AnnotationDefaultCompleter extends AnnotationDeproxy implements Runnable {
1880         final MethodSymbol sym;
1881         final Attribute value;
1882         final JavaFileObject classFile = currentClassFile;
1883 



1884         AnnotationDefaultCompleter(MethodSymbol sym, Attribute value) {
1885             super(currentOwner.kind == MTH
1886                     ? currentOwner.enclClass() : (ClassSymbol)currentOwner);
1887             this.sym = sym;
1888             this.value = value;
1889         }
1890 
1891         @Override
1892         public void run() {
1893             JavaFileObject previousClassFile = currentClassFile;
1894             try {
1895                 // Reset the interim value set earlier in
1896                 // attachAnnotationDefault().
1897                 sym.defaultValue = null;
1898                 currentClassFile = classFile;
1899                 sym.defaultValue = deproxy(sym.type.getReturnType(), value);
1900             } finally {
1901                 currentClassFile = previousClassFile;
1902             }
1903         }
1904 
1905         @Override
1906         public String toString() {
1907             return " ClassReader store default for " + sym.owner + "." + sym + " is " + value;
1908         }
1909     }
1910 
1911     class AnnotationCompleter extends AnnotationDeproxy implements Runnable {
1912         final Symbol sym;
1913         final List<CompoundAnnotationProxy> l;
1914         final JavaFileObject classFile;
1915 



1916         AnnotationCompleter(Symbol sym, List<CompoundAnnotationProxy> l) {
1917             super(currentOwner.kind == MTH
1918                     ? currentOwner.enclClass() : (ClassSymbol)currentOwner);
1919             this.sym = sym;
1920             this.l = l;
1921             this.classFile = currentClassFile;
1922         }
1923 
1924         @Override
1925         public void run() {
1926             JavaFileObject previousClassFile = currentClassFile;
1927             try {
1928                 currentClassFile = classFile;
1929                 List<Attribute.Compound> newList = deproxyCompoundList(l);
1930                 if (sym.annotationsPendingCompletion()) {
1931                     sym.setDeclarationAttributes(newList);
1932                 } else {
1933                     sym.appendAttributes(newList);
1934                 }
1935             } finally {
1936                 currentClassFile = previousClassFile;
1937             }
1938         }
1939 
1940         @Override
1941         public String toString() {
1942             return " ClassReader annotate " + sym.owner + "." + sym + " with " + l;
1943         }
1944     }
1945 
1946     class TypeAnnotationCompleter extends AnnotationCompleter {
1947 
1948         List<TypeAnnotationProxy> proxies;
1949 
1950         TypeAnnotationCompleter(Symbol sym,
1951                 List<TypeAnnotationProxy> proxies) {
1952             super(sym, List.<CompoundAnnotationProxy>nil());
1953             this.proxies = proxies;
1954         }
1955 
1956         List<Attribute.TypeCompound> deproxyTypeCompoundList(List<TypeAnnotationProxy> proxies) {
1957             ListBuffer<Attribute.TypeCompound> buf = new ListBuffer<>();
1958             for (TypeAnnotationProxy proxy: proxies) {
1959                 Attribute.Compound compound = deproxyCompound(proxy.compound);
1960                 Attribute.TypeCompound typeCompound = new Attribute.TypeCompound(compound, proxy.position);
1961                 buf.add(typeCompound);
1962             }
1963             return buf.toList();


2303         else if (checkClassFile &&
2304                  majorVersion == maxMajor &&
2305                  minorVersion > maxMinor)
2306         {
2307             printCCF("found.later.version",
2308                      Integer.toString(minorVersion));
2309         }
2310         indexPool();
2311         if (signatureBuffer.length < bp) {
2312             int ns = Integer.highestOneBit(bp) << 1;
2313             signatureBuffer = new byte[ns];
2314         }
2315         readClass(c);
2316     }
2317 
2318     public void readClassFile(ClassSymbol c) {
2319         currentOwner = c;
2320         currentClassFile = c.classfile;
2321         warnedAttrs.clear();
2322         filling = true;
2323         target = null;
2324         repeatable = null;
2325         try {
2326             bp = 0;
2327             buf = readInputStream(buf, c.classfile.openInputStream());
2328             readClassBuffer(c);
2329             if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) {
2330                 List<Type> missing = missingTypeVariables;
2331                 List<Type> found = foundTypeVariables;
2332                 missingTypeVariables = List.nil();
2333                 foundTypeVariables = List.nil();
2334                 filling = false;
2335                 ClassType ct = (ClassType)currentOwner.type;
2336                 ct.supertype_field =
2337                     types.subst(ct.supertype_field, missing, found);
2338                 ct.interfaces_field =
2339                     types.subst(ct.interfaces_field, missing, found);
2340             } else if (missingTypeVariables.isEmpty() !=
2341                        foundTypeVariables.isEmpty()) {
2342                 Name name = missingTypeVariables.head.tsym.name;
2343                 throw badClassFile("undecl.type.var", name);
2344             }
2345 
2346             if ((c.flags_field & Flags.ANNOTATION) != 0) {
2347                 c.setAnnotationTypeMetadata(new AnnotationTypeMetadata(c, new CompleterDeproxy(c, target, repeatable)));
2348             } else {
2349                 c.setAnnotationTypeMetadata(AnnotationTypeMetadata.notAnAnnotationType());
2350             }
2351         } catch (IOException ex) {
2352             throw badClassFile("unable.to.access.file", ex.getMessage());
2353         } catch (ArrayIndexOutOfBoundsException ex) {
2354             throw badClassFile("bad.class.file", c.flatname);
2355         } finally {
2356             missingTypeVariables = List.nil();
2357             foundTypeVariables = List.nil();
2358             filling = false;
2359         }
2360     }
2361     // where
2362         private static byte[] readInputStream(byte[] buf, InputStream s) throws IOException {
2363             try {
2364                 buf = ensureCapacity(buf, s.available());
2365                 int r = s.read(buf);
2366                 int bp = 0;
2367                 while (r != -1) {
2368                     bp += r;
2369                     buf = ensureCapacity(buf, bp);
2370                     r = s.read(buf, bp, buf.length - bp);


2528          * SourceFile attribute, and do not directly represent specific files.
2529          * Two SourceFileObjects are equal if their names are equal.
2530          */
2531         @Override
2532         public boolean equals(Object other) {
2533             if (this == other)
2534                 return true;
2535 
2536             if (!(other instanceof SourceFileObject))
2537                 return false;
2538 
2539             SourceFileObject o = (SourceFileObject) other;
2540             return name.equals(o.name);
2541         }
2542 
2543         @Override
2544         public int hashCode() {
2545             return name.hashCode();
2546         }
2547     }
2548 
2549     private class CompleterDeproxy implements AnnotationTypeCompleter {
2550         ClassSymbol proxyOn;
2551         CompoundAnnotationProxy target;
2552         CompoundAnnotationProxy repeatable;
2553 
2554         public CompleterDeproxy(ClassSymbol c, CompoundAnnotationProxy target,
2555                 CompoundAnnotationProxy repeatable)
2556         {
2557             this.proxyOn = c;
2558             this.target = target;
2559             this.repeatable = repeatable;
2560         }
2561 
2562         @Override
2563         public void complete(ClassSymbol sym) {
2564             Assert.check(proxyOn == sym);
2565             Attribute.Compound theTarget = null, theRepeatable = null;
2566             AnnotationDeproxy deproxy;
2567 
2568             try {
2569                 if (target != null) {
2570                     deproxy = new AnnotationDeproxy(proxyOn);
2571                     theTarget = deproxy.deproxyCompound(target);
2572                 }
2573 
2574                 if (repeatable != null) {
2575                     deproxy = new AnnotationDeproxy(proxyOn);
2576                     theRepeatable = deproxy.deproxyCompound(repeatable);
2577                 }
2578             } catch (Exception e) {
2579                 throw new CompletionFailure(sym, e.getMessage());
2580             }
2581 
2582             sym.getAnnotationTypeMetadata().setTarget(theTarget);
2583             sym.getAnnotationTypeMetadata().setRepeatable(theRepeatable);
2584         }
2585     }
2586 }
< prev index next >