/* * 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); } }
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(); }
/** * Complete the initialization of an operator helper by storing it into the corresponding operator * map. */ @SafeVarargs private final <O extends OperatorHelper> void initOperators(Map<Name, List<O>> opsMap, O... ops) { for (O o : ops) { Name opName = o.name; List<O> helpers = opsMap.getOrDefault(opName, List.nil()); opsMap.put(opName, helpers.prepend(o)); } }
/** * 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<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(); }
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(); }
/** 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(); }
/** * Returns the elements of this annotation type. Returns an empty array if there are none. * Elements are always public, so no need to filter them. */ public AnnotationTypeElementDoc[] elements() { Name.Table names = tsym.name.table; List<AnnotationTypeElementDoc> elements = new List<AnnotationTypeElementDoc>(); for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) { if (e.sym != null && e.sym.kind == Kinds.MTH) { MethodSymbol s = (MethodSymbol) e.sym; elements = elements.prepend(env.getAnnotationTypeElementDoc(s)); } } return elements.toArray(new AnnotationTypeElementDoc[elements.length()]); }
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(); }
public String simplify(Symbol s) { String name = s.getQualifiedName().toString(); if (!s.type.isCompound()) { List<Symbol> conflicts = nameClashes.get(s.getSimpleName()); if (conflicts == null || (conflicts.size() == 1 && conflicts.contains(s))) { List<Name> l = List.nil(); Symbol s2 = s; while (s2.type.getEnclosingType().tag == CLASS && s2.owner.kind == Kinds.TYP) { l = l.prepend(s2.getSimpleName()); s2 = s2.owner; } l = l.prepend(s2.getSimpleName()); StringBuilder buf = new StringBuilder(); String sep = ""; for (Name n2 : l) { buf.append(sep); buf.append(n2); sep = "."; } name = buf.toString(); } } return name; }
private JCExpression makeDefaultValueCall(Parameter defaultedParam, int i) { // add the default value List<JCExpression> defaultMethodArgs = List.nil(); // pass all the previous values for (int a = i - 1; a >= 0; a--) { Parameter param = paramLists.getParameters().get(a); JCExpression previousValue = gen.makeUnquotedIdent(getCallableTempVarName(param)); defaultMethodArgs = defaultMethodArgs.prepend(previousValue); } // now call the default value method return gen.make() .Apply( null, gen.makeUnquotedIdent(Naming.getDefaultedParamMethodName(null, defaultedParam)), defaultMethodArgs); }
@Override public String visitCapturedType(CapturedType t, Locale locale) { if (seenCaptured.contains(t)) return localize(locale, "compiler.misc.type.captureof.1", capturedVarId(t, locale)); else { try { seenCaptured = seenCaptured.prepend(t); return localize( locale, "compiler.misc.type.captureof", capturedVarId(t, locale), visit(t.wildcard, locale)); } finally { seenCaptured = seenCaptured.tail; } } }
@Override public Void visitClassType(ClassType t, Void ignored) { if (t.isCompound()) { if (indexOf(t, WhereClauseKind.INTERSECTION) == -1) { Type supertype = types.supertype(t); List<Type> interfaces = types.interfaces(t); JCDiagnostic d = diags.fragment("where.intersection", t, interfaces.prepend(supertype)); whereClauses.get(WhereClauseKind.INTERSECTION).put(t, d); visit(supertype); visit(interfaces); } } nameSimplifier.addUsage(t.tsym); visit(t.getTypeArguments()); if (t.getEnclosingType() != Type.noType) visit(t.getEnclosingType()); return null; }
/** 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(); }
@Override public JCTree visitConstructorDecl(final lombok.ast.ConstructorDecl node, final Void p) { final JCModifiers mods = setGeneratedBy( M(node) .Modifiers( flagsFor(node.getModifiers()), build(node.getAnnotations(), JCAnnotation.class)), source); List<JCStatement> statements = build(node.getStatements(), JCStatement.class); if (node.implicitSuper()) { statements = statements.prepend(build(Call("super"), JCStatement.class)); } final List<JCTypeParameter> typarams = build(node.getTypeParameters()); final List<JCVariableDecl> params = build(node.getArguments()); final List<JCExpression> thrown = build(node.getThrownExceptions()); final JCBlock body = setGeneratedBy(M(node).Block(0, statements), source); final JCMethodDecl constructor = setGeneratedBy( M(node).MethodDef(mods, name("<init>"), null, typarams, params, thrown, body, null), source); return constructor; }
private static <T> com.sun.tools.javac.util.List<T> toJavacList(List<T> list) { com.sun.tools.javac.util.List<T> out = com.sun.tools.javac.util.List.nil(); ListIterator<T> li = list.listIterator(list.size()); while (li.hasPrevious()) out = out.prepend(li.previous()); return out; }
/** * Programmatic interface for main function. * * @param args The command line parameters. */ public int compile( String[] args, Context context, List<JavaFileObject> fileObjects, Iterable<? extends Processor> processors) { if (options == null) options = Options.instance(context); // creates a new one filenames = new ListBuffer<File>(); classnames = new ListBuffer<String>(); JavaCompiler comp = null; /* * TODO: Logic below about what is an acceptable command line * should be updated to take annotation processing semantics * into account. */ try { if (args.length == 0 && fileObjects.isEmpty()) { help(); return EXIT_CMDERR; } List<File> files; try { files = processArgs(CommandLine.parse(args)); if (files == null) { // null signals an error in options, abort return EXIT_CMDERR; } else if (files.isEmpty() && fileObjects.isEmpty() && classnames.isEmpty()) { // it is allowed to compile nothing if just asking for help or version info if (options.get("-help") != null || options.get("-X") != null || options.get("-version") != null || options.get("-fullversion") != null) return EXIT_OK; error("err.no.source.files"); return EXIT_CMDERR; } } catch (java.io.FileNotFoundException e) { Log.printLines( out, ownName + ": " + getLocalizedString("err.file.not.found", e.getMessage())); return EXIT_SYSERR; } boolean forceStdOut = options.get("stdout") != null; if (forceStdOut) { out.flush(); out = new PrintWriter(System.out, true); } context.put(Log.outKey, out); // allow System property in following line as a Mustang legacy boolean batchMode = (options.get("nonBatchMode") == null && System.getProperty("nonBatchMode") == null); if (batchMode) CacheFSInfo.preRegister(context); fileManager = context.get(JavaFileManager.class); comp = JavaCompiler.instance(context); if (comp == null) return EXIT_SYSERR; if (!files.isEmpty()) { // add filenames to fileObjects comp = JavaCompiler.instance(context); List<JavaFileObject> otherFiles = List.nil(); JavacFileManager dfm = (JavacFileManager) fileManager; for (JavaFileObject fo : dfm.getJavaFileObjectsFromFiles(files)) otherFiles = otherFiles.prepend(fo); for (JavaFileObject fo : otherFiles) fileObjects = fileObjects.prepend(fo); } comp.compile(fileObjects, classnames.toList(), processors); if (comp.errorCount() != 0) return EXIT_ERROR; } catch (IOException ex) { ioMessage(ex); return EXIT_SYSERR; } catch (OutOfMemoryError ex) { resourceMessage(ex); return EXIT_SYSERR; } catch (StackOverflowError ex) { resourceMessage(ex); return EXIT_SYSERR; } catch (FatalError ex) { feMessage(ex); return EXIT_SYSERR; } catch (AnnotationProcessingError ex) { apMessage(ex); return EXIT_SYSERR; } catch (ClientCodeException ex) { // as specified by javax.tools.JavaCompiler#getTask // and javax.tools.JavaCompiler.CompilationTask#call throw new RuntimeException(ex.getCause()); } catch (PropagatedException ex) { throw ex.getCause(); } catch (Throwable ex) { // Nasty. If we've already reported an error, compensate // for buggy compiler error recovery by swallowing thrown // exceptions. if (comp == null || comp.errorCount() == 0 || options == null || options.get("dev") != null) bugMessage(ex); return EXIT_ABNORMAL; } finally { if (comp != null) comp.close(); filenames = null; options = null; } return EXIT_OK; }
private JCTree makeDefaultedCall( int i, boolean isVariadic, java.util.List<ProducedType> parameterTypes) { // collect every parameter int a = 0; ListBuffer<JCStatement> stmts = new ListBuffer<JCStatement>(); for (Parameter param : paramLists.getParameters()) { // don't read default parameter values for forwarded calls if (forwardCallTo != null && i == a) break; // read the value JCExpression paramExpression = getTypedParameter(param, a, i > 3, parameterTypes); JCExpression varInitialExpression; if (param.isDefaulted() || param.isSequenced()) { if (i > 3) { // must check if it's defined JCExpression test = gen.make() .Binary(JCTree.GT, gen.makeSelect(getParamName(0), "length"), gen.makeInteger(a)); JCExpression elseBranch = makeDefaultValueCall(param, a); varInitialExpression = gen.make().Conditional(test, paramExpression, elseBranch); } else if (a >= i) { // get its default value because we don't have it varInitialExpression = makeDefaultValueCall(param, a); } else { // we must have it varInitialExpression = paramExpression; } } else { varInitialExpression = paramExpression; } // store it in a local var JCStatement var = gen.make() .VarDef( gen.make().Modifiers(Flags.FINAL), gen.naming.makeUnquotedName(getCallableTempVarName(param)), gen.makeJavaType( parameterTypes.get(a), CodegenUtil.isUnBoxed(param) ? 0 : gen.JT_NO_PRIMITIVES), varInitialExpression); stmts.append(var); a++; } if (forwardCallTo != null) { InvocationBuilder invocationBuilder = InvocationBuilder.forCallableInvocation(gen, forwardCallTo, paramLists, i); boolean prevCallableInv = gen.expressionGen().withinCallableInvocation(true); try { stmts.append(gen.make().Return(invocationBuilder.build())); } finally { gen.expressionGen().withinCallableInvocation(prevCallableInv); } } else if (isVariadic) { // chain to n param typed method List<JCExpression> args = List.nil(); // pass along the parameters for (a = paramLists.getParameters().size() - 1; a >= 0; a--) { Parameter param = paramLists.getParameters().get(a); args = args.prepend(gen.makeUnquotedIdent(getCallableTempVarName(param))); } JCMethodInvocation chain = gen.make().Apply(null, gen.makeUnquotedIdent(Naming.getCallableTypedMethodName()), args); stmts.append(gen.make().Return(chain)); } else { // insert the method body directly stmts.appendList(this.body); } List<JCStatement> body = stmts.toList(); return makeCallMethod(body, i); }