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 }
|