/* * 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 Module loadModuleFromSource(String pkgName, LinkedList<JCCompilationUnit> moduleTrees) { if (pkgName.isEmpty()) return null; String moduleClassName = pkgName + ".module"; JavaFileObject fileObject; try { if (options.get(OptionName.VERBOSE) != null) { Log.printLines(log.noticeWriter, "[Trying to load module " + moduleClassName + "]"); } fileObject = fileManager.getJavaFileForInput( StandardLocation.SOURCE_PATH, moduleClassName, Kind.SOURCE); if (options.get(OptionName.VERBOSE) != null) { Log.printLines(log.noticeWriter, "[Got file object: " + fileObject + "]"); } } catch (IOException e) { e.printStackTrace(); return loadModuleFromSource(getParentPackage(pkgName), moduleTrees); } if (fileObject != null) { CeylonCompilationUnit ceylonCompilationUnit = (CeylonCompilationUnit) parse(fileObject); moduleTrees.add(ceylonCompilationUnit); // parse the module info from there Module module = ceylonCompilationUnit.phasedUnit.visitSrcModulePhase(); ceylonCompilationUnit.phasedUnit.visitRemainingModulePhase(); // now try to obtain the parsed module if (module != null) { ceylonCompilationUnit.phasedUnit.getPackage().setModule(module); return module; } } return loadModuleFromSource(getParentPackage(pkgName), moduleTrees); }
public boolean hasNext() { if (nextProc != null) return true; else { if (!names.hasNext()) return false; else { String processorName = names.next(); Processor processor; try { try { processor = (Processor) (processorCL.loadClass(processorName).newInstance()); } catch (ClassNotFoundException cnfe) { log.error("proc.processor.not.found", processorName); return false; } catch (ClassCastException cce) { log.error("proc.processor.wrong.type", processorName); return false; } catch (Exception e) { log.error("proc.processor.cant.instantiate", processorName); return false; } } catch (ClientCodeException e) { throw e; } catch (Throwable t) { throw new AnnotationProcessingError(t); } nextProc = processor; return true; } } }
/** Handle a security exception thrown during initializing the Processor iterator. */ private void handleException(String key, Exception e) { if (e != null) { log.error(key, e.getLocalizedMessage()); throw new Abort(e); } else { log.error(key); throw new Abort(); } }
public Processor next() { try { return (Processor) (iterator.next()); } catch (Throwable t) { if ("ServiceConfigurationError".equals(t.getClass().getSimpleName())) { log.error("proc.bad.config.file", t.getLocalizedMessage()); } else { log.error("proc.processor.constructor.error", t.getLocalizedMessage()); } throw new Abort(t); } }
/** Create the compiler to be used for the final compilation. */ JavaCompiler finalCompiler(boolean errorStatus) { try { JavaCompiler c = JavaCompiler.instance(nextContext()); c.log.nwarnings += compiler.log.nwarnings; if (errorStatus) { c.log.nerrors += compiler.log.nerrors; } return c; } finally { compiler.close(false); } }
/** Print a string that explains usage for X options. */ void xhelp() { for (int i = 0; i < recognizedOptions.length; i++) { recognizedOptions[i].xhelp(out); } out.println(); Log.printLines(out, getLocalizedString("msg.usage.nonstandard.footer")); }
/** Print a string that explains usage. */ void help() { Log.printLines(out, getLocalizedString("msg.usage.header", ownName)); for (int i = 0; i < recognizedOptions.length; i++) { recognizedOptions[i].help(out); } out.println(); }
/** Print info about this round. */ private void printRoundInfo(boolean lastRound) { if (printRounds || verbose) { List<ClassSymbol> tlc = lastRound ? List.<ClassSymbol>nil() : topLevelClasses; Set<TypeElement> ap = lastRound ? Collections.<TypeElement>emptySet() : annotationsPresent; log.printNoteLines("x.print.rounds", number, "{" + tlc.toString(", ") + "}", ap, lastRound); } }
void setContext(Context context) { log = Log.instance(context); options = Options.instance(context); lint = Lint.instance(context); fsInfo = FSInfo.instance(context); config = CompilerConfig.instance(context); }
/** Construct a new compiler from a shared context. */ public AptJavaCompiler(Context context) { super(preRegister(context)); context.put(compilerKey, this); apt = Apt.instance(context); ClassReader classReader = ClassReader.instance(context); classReader.preferSource = true; // TEMPORARY NOTE: bark==log, but while refactoring, we maintain their // original identities, to remember the original intent. log = Log.instance(context); bark = Bark.instance(context); Options options = Options.instance(context); classOutput = options.get("-retrofit") == null; nocompile = options.get("-nocompile") != null; print = options.get("-print") != null; classesAsDecls = options.get("-XclassesAsDecls") != null; genSourceFileNames = new java.util.LinkedHashSet<String>(); genClassFileNames = new java.util.LinkedHashSet<String>(); // this forces a copy of the line map to be kept in the tree, // for use by com.sun.mirror.util.SourcePosition. lineDebugInfo = true; }
public JavacProcessingEnvironment(Context context, Iterable<? extends Processor> processors) { this.context = context; log = Log.instance(context); source = Source.instance(context); diags = JCDiagnostic.Factory.instance(context); options = Options.instance(context); printProcessorInfo = options.isSet(XPRINTPROCESSORINFO); printRounds = options.isSet(XPRINTROUNDS); verbose = options.isSet(VERBOSE); lint = Lint.instance(context).isEnabled(PROCESSING); procOnly = options.isSet(PROC, "only") || options.isSet(XPRINT); fatalErrors = options.isSet("fatalEnterError"); showResolveErrors = options.isSet("showResolveErrors"); werror = options.isSet(WERROR); platformAnnotations = initPlatformAnnotations(); foundTypeProcessors = false; // Initialize services before any processors are initialized // in case processors use them. filer = new JavacFiler(context); messager = new JavacMessager(context, this); elementUtils = JavacElements.instance(context); typeUtils = JavacTypes.instance(context); processorOptions = initProcessorOptions(context); unmatchedProcessorOptions = initUnmatchedProcessorOptions(); messages = JavacMessages.instance(context); initProcessorIterator(context, processors); }
/** * Process a single compound annotation, returning its Attribute. Used from MemberEnter for * attaching the attributes to the annotated symbol. */ Attribute.Compound enterAnnotation(JCAnnotation a, Type expected, Env<AttrContext> env) { // The annotation might have had its type attributed (but not checked) // by attr.attribAnnotationTypes during MemberEnter, in which case we do not // need to do it again. Type at = (a.annotationType.type != null ? a.annotationType.type : attr.attribType(a.annotationType, env)); a.type = chk.checkType(a.annotationType.pos(), at, expected); if (a.type.isErroneous()) return new Attribute.Compound(a.type, List.<Pair<MethodSymbol, Attribute>>nil()); if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0) { log.error(a.annotationType.pos(), "not.annotation.type", a.type.toString()); return new Attribute.Compound(a.type, List.<Pair<MethodSymbol, Attribute>>nil()); } List<JCExpression> args = a.args; if (args.length() == 1 && args.head.getTag() != JCTree.ASSIGN) { // special case: elided "value=" assumed args.head = make.at(args.head.pos).Assign(make.Ident(names.value), args.head); } ListBuffer<Pair<MethodSymbol, Attribute>> buf = new ListBuffer<Pair<MethodSymbol, Attribute>>(); for (List<JCExpression> tl = args; tl.nonEmpty(); tl = tl.tail) { JCExpression t = tl.head; if (t.getTag() != JCTree.ASSIGN) { log.error(t.pos(), "annotation.value.must.be.name.value"); continue; } JCAssign assign = (JCAssign) t; if (assign.lhs.getTag() != JCTree.IDENT) { log.error(t.pos(), "annotation.value.must.be.name.value"); continue; } JCIdent left = (JCIdent) assign.lhs; Symbol method = rs.resolveQualifiedMethod(left.pos(), env, a.type, left.name, List.<Type>nil(), null); left.sym = method; left.type = method.type; if (method.owner != a.type.tsym) log.error(left.pos(), "no.annotation.member", left.name, a.type); Type result = method.type.getReturnType(); Attribute value = enterAttributeValue(result, assign.rhs, env); if (!method.type.isErroneous()) buf.append(new Pair<MethodSymbol, Attribute>((MethodSymbol) method, value)); t.type = result; } return new Attribute.Compound(a.type, buf.toList()); }
/** Create a round (common code). */ private Round(Context context, int number, int priorErrors, int priorWarnings) { this.context = context; this.number = number; compiler = JavaCompiler.instance(context); log = Log.instance(context); log.nerrors = priorErrors; log.nwarnings += priorWarnings; log.deferDiagnostics = true; // the following is for the benefit of JavacProcessingEnvironment.getContext() JavacProcessingEnvironment.this.context = context; // the following will be populated as needed topLevelClasses = List.nil(); packageInfoFiles = List.nil(); }
/** Report a usage error. */ void error(String key, Object... args) { if (fatalErrors) { String msg = getLocalizedString(key, args); throw new PropagatedException(new IllegalStateException(msg)); } warning(key, args); Log.printLines(out, getLocalizedString("msg.usage", ownName)); }
/** * Convert import-style string for supported annotations into a regex matching that string. If the * string is a valid import-style string, return a regex that won't match anything. */ private static Pattern importStringToPattern(String s, Processor p, Log log) { if (isValidImportString(s)) { return validImportStringToPattern(s); } else { log.warning("proc.malformed.supported.string", s, p.getClass().getName()); return noMatches; // won't match any valid identifier } }
void showDiagnostics(boolean showAll) { Set<JCDiagnostic.Kind> kinds = EnumSet.allOf(JCDiagnostic.Kind.class); if (!showAll) { // suppress errors, which are all presumed to be transient resolve errors kinds.remove(JCDiagnostic.Kind.ERROR); } log.reportDeferredDiagnostics(kinds); }
public void visitTopLevel(JCCompilationUnit tree) { JavaFileObject prev = log.useSource(tree.sourcefile); boolean addEnv = false; boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE); if (tree.pid != null) { tree.packge = reader.enterPackage(TreeInfo.fullName(tree.pid)); if (tree.packageAnnotations.nonEmpty()) { if (isPkgInfo) { addEnv = true; } else { log.error(tree.packageAnnotations.head.pos(), "pkg.annotations.sb.in.package-info.java"); } } } else { tree.packge = syms.unnamedPackage; } tree.packge.complete(); // Find all classes in package. Env<AttrContext> env = topLevelEnv(tree); // Save environment of package-info.java file. if (isPkgInfo) { Env<AttrContext> env0 = typeEnvs.get(tree.packge); if (env0 == null) { typeEnvs.put(tree.packge, env); } else { JCCompilationUnit tree0 = env0.toplevel; if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) { log.warning( tree.pid != null ? tree.pid.pos() : null, "pkg-info.already.seen", tree.packge); if (addEnv || (tree0.packageAnnotations.isEmpty() && tree.docComments != null && tree.docComments.get(tree) != null)) { typeEnvs.put(tree.packge, env); } } } } classEnter(tree.defs, env); if (addEnv) { todo.append(env); } log.useSource(prev); result = null; }
private boolean callProcessor( Processor proc, Set<? extends TypeElement> tes, RoundEnvironment renv) { try { return proc.process(tes, renv); } catch (BadClassFile ex) { log.error("proc.cant.access.1", ex.sym, ex.getDetailValue()); return false; } catch (CompletionFailure ex) { StringWriter out = new StringWriter(); ex.printStackTrace(new PrintWriter(out)); log.error("proc.cant.access", ex.sym, ex.getDetailValue(), out.toString()); return false; } catch (ClientCodeException e) { throw e; } catch (Throwable t) { throw new AnnotationProcessingError(t); } }
protected Operators(Context context) { context.put(operatorsKey, this); syms = Symtab.instance(context); names = Names.instance(context); log = Log.instance(context); types = Types.instance(context); initOperatorNames(); initUnaryOperators(); initBinaryOperators(); }
/** Construct a new module finder. */ protected ModuleFinder(Context context) { context.put(moduleFinderKey, this); names = Names.instance(context); syms = Symtab.instance(context); fileManager = context.get(JavaFileManager.class); log = Log.instance(context); classFinder = ClassFinder.instance(context); diags = JCDiagnostic.Factory.instance(context); }
public boolean hasNext() { try { return iterator.hasNext(); } catch (Throwable t) { if ("ServiceConfigurationError".equals(t.getClass().getSimpleName())) { log.error("proc.bad.config.file", t.getLocalizedMessage()); } throw new Abort(t); } }
/** * Checks whether or not a processor's source version is compatible with the compilation source * version. The processor's source version needs to be greater than or equal to the source * version of the compile. */ private void checkSourceVersionCompatibility(Source source, Log log) { SourceVersion procSourceVersion = processor.getSupportedSourceVersion(); if (procSourceVersion.compareTo(Source.toSourceVersion(source)) < 0) { log.warning( "proc.processor.incompatible.source.version", procSourceVersion, processor.getClass().getName(), source.name); } }
/** Report an operator lookup error. */ private Symbol reportErrorIfNeeded(DiagnosticPosition pos, Tag tag, Type... args) { if (Stream.of(args).noneMatch(Type::isErroneous)) { Name opName = operatorName(tag); JCDiagnostic.Error opError = (args.length) == 1 ? Errors.OperatorCantBeApplied(opName, args[0]) : Errors.OperatorCantBeApplied1(opName, args[0], args[1]); log.error(pos, opError); } return syms.noSymbol; }
protected Annotate(Context context) { context.put(annotateKey, this); attr = Attr.instance(context); make = TreeMaker.instance(context); log = Log.instance(context); syms = Symtab.instance(context); names = Names.instance(context); rs = Resolve.instance(context); types = Types.instance(context); cfolder = ConstFold.instance(context); chk = Check.instance(context); }
protected RichDiagnosticFormatter(Context context) { super((AbstractDiagnosticFormatter) Log.instance(context).getDiagnosticFormatter()); setRichPrinter(new RichPrinter()); this.syms = Symtab.instance(context); this.diags = JCDiagnostic.Factory.instance(context); this.types = Types.instance(context); this.messages = JavacMessages.instance(context); whereClauses = new LinkedHashMap<WhereClauseKind, Map<Type, JCDiagnostic>>(); configuration = new RichConfiguration(Options.instance(context), formatter); for (WhereClauseKind kind : WhereClauseKind.values()) whereClauses.put(kind, new LinkedHashMap<Type, JCDiagnostic>()); }
public static MethodSymbol resolveMethod( VisitorState state, TypeSymbol base, Name name, Iterable<Type> argTypes, Iterable<Type> tyargTypes) { Resolve resolve = Resolve.instance(state.context); Enter enter = Enter.instance(state.context); Log log = Log.instance(state.context); DeferredDiagnosticHandler handler = new DeferredDiagnosticHandler(log); try { return resolve.resolveInternalMethod( /*pos*/ null, enter.getEnv(base), base.type, name, com.sun.tools.javac.util.List.from(argTypes), com.sun.tools.javac.util.List.from(tyargTypes)); } finally { log.popDiagnosticHandler(handler); } }
private <T extends Attribute.Compound> T replaceOne( Placeholder<T> placeholder, Annotate.AnnotateRepeatedContext<T> ctx) { Log log = ctx.log; // Process repeated annotations T validRepeated = ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor(), sym); if (validRepeated != null) { // Check that the container isn't manually // present along with repeated instances of // its contained annotation. ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym); if (manualContainer != null) { log.error( ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present", manualContainer.first().type.tsym); } } // A null return will delete the Placeholder return validRepeated; }
/** * Main method: enter one class from a list of toplevel trees and place the rest on uncompleted * for later processing. * * @param trees The list of trees to be processed. * @param c The class symbol to be processed. */ public void complete(List<JCCompilationUnit> trees, ClassSymbol c) { annotate.enterStart(); ListBuffer<ClassSymbol> prevUncompleted = uncompleted; if (memberEnter.completionEnabled) uncompleted = new ListBuffer<ClassSymbol>(); try { // enter all classes, and construct uncompleted list classEnter(trees, null); // complete all uncompleted classes in memberEnter if (memberEnter.completionEnabled) { while (uncompleted.nonEmpty()) { ClassSymbol clazz = uncompleted.next(); if (c == null || c == clazz || prevUncompleted == null) clazz.complete(); else // defer prevUncompleted.append(clazz); } // if there remain any unimported toplevels (these must have // no classes at all), process their import statements as well. for (JCCompilationUnit tree : trees) { if (tree.starImportScope.elems == null) { JavaFileObject prev = log.useSource(tree.sourcefile); Env<AttrContext> env = typeEnvs.get(tree); if (env == null) env = topLevelEnv(tree); memberEnter.memberEnter(tree, env); log.useSource(prev); } } } } finally { uncompleted = prevUncompleted; annotate.enterDone(); } }
private List<ModuleSymbol> scanModulePath(ModuleSymbol toFind) { ListBuffer<ModuleSymbol> results = new ListBuffer<>(); Map<Name, Location> namesInSet = new HashMap<>(); while (moduleLocationIterator.hasNext()) { Set<Location> locns = (moduleLocationIterator.next()); namesInSet.clear(); for (Location l : locns) { try { Name n = names.fromString(fileManager.inferModuleName(l)); if (namesInSet.put(n, l) == null) { ModuleSymbol msym = syms.enterModule(n); if (msym.sourceLocation != null || msym.classLocation != null) { // module has already been found, so ignore this instance continue; } if (moduleLocationIterator.outer == StandardLocation.MODULE_SOURCE_PATH) { msym.sourceLocation = l; if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) { msym.classLocation = fileManager.getLocationForModule( StandardLocation.CLASS_OUTPUT, msym.name.toString()); } } else { msym.classLocation = l; } if (moduleLocationIterator.outer == StandardLocation.SYSTEM_MODULES || moduleLocationIterator.outer == StandardLocation.UPGRADE_MODULE_PATH) { msym.flags_field |= Flags.SYSTEM_MODULE; } if (toFind == msym || toFind == null) { // Note: cannot return msym directly, because we must finish // processing this set first results.add(msym); } } else { log.error( Errors.DuplicateModuleOnPath(getDescription(moduleLocationIterator.outer), n)); } } catch (IOException e) { // skip location for now? log error? } } if (toFind != null && results.nonEmpty()) return results.toList(); } return results.toList(); }