/* * Replace Placeholders for repeating annotations with their containers */ private <T extends Attribute.Compound> void complete(Annotate.AnnotateRepeatedContext<T> ctx) { Log log = ctx.log; Env<AttrContext> env = ctx.env; JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); try { // TODO: can we reduce duplication in the following branches? if (ctx.isTypeCompound) { Assert.check(!isTypesEmpty()); if (isTypesEmpty()) { return; } List<Attribute.TypeCompound> result = List.nil(); for (Attribute.TypeCompound a : getTypeAttributes()) { if (a instanceof Placeholder) { @SuppressWarnings("unchecked") Placeholder<Attribute.TypeCompound> ph = (Placeholder<Attribute.TypeCompound>) a; Attribute.TypeCompound replacement = replaceOne(ph, ph.getRepeatedContext()); if (null != replacement) { result = result.prepend(replacement); } } else { result = result.prepend(a); } } type_attributes = result.reverse(); Assert.check(Annotations.this.getTypePlaceholders().isEmpty()); } else { Assert.check(!pendingCompletion()); if (isEmpty()) { return; } List<Attribute.Compound> result = List.nil(); for (Attribute.Compound a : getDeclarationAttributes()) { if (a instanceof Placeholder) { @SuppressWarnings("unchecked") Attribute.Compound replacement = replaceOne((Placeholder<T>) a, ctx); if (null != replacement) { result = result.prepend(replacement); } } else { result = result.prepend(a); } } attributes = result.reverse(); Assert.check(Annotations.this.getPlaceholders().isEmpty()); } } finally { log.useSource(oldSource); } }
/** * Build a list of multiline diagnostics containing detailed info about type-variables, captured * types, and intersection types * * @return where clause list */ protected List<JCDiagnostic> getWhereClauses() { List<JCDiagnostic> clauses = List.nil(); for (WhereClauseKind kind : WhereClauseKind.values()) { List<JCDiagnostic> lines = List.nil(); for (Map.Entry<Type, JCDiagnostic> entry : whereClauses.get(kind).entrySet()) { lines = lines.prepend(entry.getValue()); } if (!lines.isEmpty()) { String key = kind.key(); if (lines.size() > 1) key += ".1"; JCDiagnostic d = diags.fragment(key, whereClauses.get(kind).keySet()); d = new JCDiagnostic.MultilineDiagnostic(d, lines.reverse()); clauses = clauses.prepend(d); } } return clauses.reverse(); }
private List<Attribute.TypeCompound> getTypePlaceholders() { List<Attribute.TypeCompound> res = List.<Attribute.TypeCompound>nil(); for (Attribute.TypeCompound a : type_attributes) { if (a instanceof Placeholder) { res = res.prepend(a); } } return res.reverse(); }
private List<Attribute.Compound> getPlaceholders() { List<Attribute.Compound> res = List.<Attribute.Compound>nil(); for (Attribute.Compound a : filterDeclSentinels(attributes)) { if (a instanceof Placeholder) { res = res.prepend(a); } } return res.reverse(); }
private List<PackageSymbol> getPackageInfoFilesFromClasses(List<? extends ClassSymbol> syms) { List<PackageSymbol> packages = List.nil(); for (ClassSymbol sym : syms) { if (isPkgInfo(sym)) { packages = packages.prepend((PackageSymbol) sym.owner); } } return packages.reverse(); }
private List<PackageSymbol> getPackageInfoFiles(List<? extends JCCompilationUnit> units) { List<PackageSymbol> packages = List.nil(); for (JCCompilationUnit unit : units) { if (isPkgInfo(unit.sourcefile, JavaFileObject.Kind.SOURCE)) { packages = packages.prepend(unit.packge); } } return packages.reverse(); }
private List<ClassSymbol> getTopLevelClassesFromClasses(List<? extends ClassSymbol> syms) { List<ClassSymbol> classes = List.nil(); for (ClassSymbol sym : syms) { if (!isPkgInfo(sym)) { classes = classes.prepend(sym); } } return classes.reverse(); }
/** Returns the list obtained from 'l' after removing all elements 'elem' */ public static <A> List<A> filter(List<A> l, A elem) { Assert.checkNonNull(elem); List<A> res = List.nil(); for (A a : l) { if (a != null && !a.equals(elem)) { res = res.prepend(a); } } return res.reverse(); }
private <T extends Attribute.Compound> List<T> getAttributesForCompletion( final Annotate.AnnotateRepeatedContext<T> ctx) { Map<Symbol.TypeSymbol, ListBuffer<T>> annotated = ctx.annotated; boolean atLeastOneRepeated = false; List<T> buf = List.<T>nil(); for (ListBuffer<T> lb : annotated.values()) { if (lb.size() == 1) { buf = buf.prepend(lb.first()); } else { // repeated // This will break when other subtypes of Attributs.Compound // are introduced, because PlaceHolder is a subtype of TypeCompound. T res; @SuppressWarnings("unchecked") T ph = (T) new Placeholder<T>(ctx, lb.toList(), sym); res = ph; buf = buf.prepend(res); atLeastOneRepeated = true; } } if (atLeastOneRepeated) { // The Symbol s is now annotated with a combination of // finished non-repeating annotations and placeholders for // repeating annotations. // // We need to do this in two passes because when creating // a container for a repeating annotation we must // guarantee that the @Repeatable on the // contained annotation is fully annotated // // The way we force this order is to do all repeating // annotations in a pass after all non-repeating are // finished. This will work because @Repeatable // is non-repeating and therefore will be annotated in the // fist pass. // Queue a pass that will replace Attribute.Placeholders // with Attribute.Compound (made from synthesized containers). ctx.annotateRepeated( new Annotate.Annotator() { @Override public String toString() { return "repeated annotation pass of: " + sym + " in: " + sym.owner; } @Override public void enterAnnotation() { complete(ctx); } }); } // Add non-repeating attributes return buf.reverse(); }
private List<ClassSymbol> getTopLevelClasses(List<? extends JCCompilationUnit> units) { List<ClassSymbol> classes = List.nil(); for (JCCompilationUnit unit : units) { for (JCTree node : unit.defs) { if (node.getTag() == JCTree.CLASSDEF) { ClassSymbol sym = ((JCClassDecl) node).sym; Assert.checkNonNull(sym); classes = classes.prepend(sym); } } } return classes.reverse(); }
/** Create the first round. */ Round(Context context, List<JCCompilationUnit> roots, List<ClassSymbol> classSymbols) { this(context, 1, 0, 0); this.roots = roots; genClassFiles = new HashMap<String, JavaFileObject>(); compiler.todo.clear(); // free the compiler's resources // The reverse() in the following line is to maintain behavioural // compatibility with the previous revision of the code. Strictly speaking, // it should not be necessary, but a javah golden file test fails without it. topLevelClasses = getTopLevelClasses(roots).prependList(classSymbols.reverse()); packageInfoFiles = getPackageInfoFiles(roots); findAnnotationsPresent(); }
/** Prepend given list of elements to front of list, forming and returning a new list. */ public List<A> prependList(List<A> xs) { if (this.isEmpty()) return xs; if (xs.isEmpty()) return this; if (xs.tail.isEmpty()) return prepend(xs.head); // return this.prependList(xs.tail).prepend(xs.head); List<A> result = this; List<A> rev = xs.reverse(); Assert.check(rev != xs); // since xs.reverse() returned a new list, we can reuse the // individual List objects, instead of allocating new ones. while (rev.nonEmpty()) { List<A> h = rev; rev = rev.tail; h.setTail(result); result = h; } return result; }
/** Enter a set of generated class files. */ private List<ClassSymbol> enterClassFiles(Map<String, JavaFileObject> classFiles) { ClassReader reader = ClassReader.instance(context); Names names = Names.instance(context); List<ClassSymbol> list = List.nil(); for (Map.Entry<String, JavaFileObject> entry : classFiles.entrySet()) { Name name = names.fromString(entry.getKey()); JavaFileObject file = entry.getValue(); if (file.getKind() != JavaFileObject.Kind.CLASS) throw new AssertionError(file); ClassSymbol cs; if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) { Name packageName = Convert.packagePart(name); PackageSymbol p = reader.enterPackage(packageName); if (p.package_info == null) p.package_info = reader.enterClass(Convert.shortName(name), p); cs = p.package_info; if (cs.classfile == null) cs.classfile = file; } else cs = reader.enterClass(name, file); list = list.prepend(cs); } return list.reverse(); }