Search in sources :

Example 11 with UserError

use of org.checkerframework.javacutil.UserError in project checker-framework by typetools.

the class SourceChecker method typeProcess.

/**
 * Type-check the code using this checker's visitor.
 *
 * @see Processor#process(Set, RoundEnvironment)
 */
@Override
public void typeProcess(TypeElement e, TreePath p) {
    if (javacErrored) {
        reportJavacError(p);
        return;
    }
    // Cannot use BugInCF here because it is outside of the try/catch for BugInCF.
    if (e == null) {
        messager.printMessage(Kind.ERROR, "Refusing to process empty TypeElement");
        return;
    }
    if (p == null) {
        messager.printMessage(Kind.ERROR, "Refusing to process empty TreePath in TypeElement: " + e);
        return;
    }
    if (!warnedAboutGarbageCollection) {
        String gcUsageMessage = SystemPlume.gcUsageMessage(.25, 60);
        if (gcUsageMessage != null) {
            messager.printMessage(Kind.WARNING, gcUsageMessage);
            warnedAboutGarbageCollection = true;
        }
    }
    Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
    Source source = Source.instance(context);
    // Also the enum constant Source.JDK1_8 was renamed at some point...
    if (!warnedAboutSourceLevel && source.compareTo(Source.lookup("8")) < 0) {
        messager.printMessage(Kind.WARNING, "-source " + source.name + " does not support type annotations");
        warnedAboutSourceLevel = true;
    }
    Log log = Log.instance(context);
    if (log.nerrors > this.errsOnLastExit) {
        this.errsOnLastExit = log.nerrors;
        javacErrored = true;
        reportJavacError(p);
        return;
    }
    if (visitor == null) {
        // there. Don't also cause a NPE here.
        return;
    }
    if (p.getCompilationUnit() != currentRoot) {
        setRoot(p.getCompilationUnit());
        if (hasOption("filenames")) {
            // TODO: Have a command-line option to turn the timestamps on/off too, because
            // they are nondeterministic across runs.
            // Add timestamp to indicate how long operations are taking.
            // Duplicate messages are suppressed, so this might not appear in front of every "
            // is type-checking " message (when a file takes less than a second to type-check).
            message(Kind.NOTE, Instant.now().toString());
            message(Kind.NOTE, "%s is type-checking %s", (Object) this.getClass().getSimpleName(), currentRoot.getSourceFile().getName());
        }
    }
    // Visit the attributed tree.
    try {
        visitor.visit(p);
        warnUnneededSuppressions();
    } catch (UserError ce) {
        logUserError(ce);
    } catch (TypeSystemError ce) {
        logTypeSystemError(ce);
    } catch (BugInCF ce) {
        logBugInCF(ce);
    } catch (Throwable t) {
        logBugInCF(wrapThrowableAsBugInCF("SourceChecker.typeProcess", t, p));
    } finally {
        // Also add possibly deferred diagnostics, which will get published back in
        // AbstractTypeProcessor.
        this.errsOnLastExit = log.nerrors;
    }
}
Also used : Context(com.sun.tools.javac.util.Context) UserError(org.checkerframework.javacutil.UserError) Log(com.sun.tools.javac.util.Log) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment) TypeSystemError(org.checkerframework.javacutil.TypeSystemError) BugInCF(org.checkerframework.javacutil.BugInCF) Source(com.sun.tools.javac.code.Source) DiagnosticSource(com.sun.tools.javac.util.DiagnosticSource)

Example 12 with UserError

use of org.checkerframework.javacutil.UserError in project checker-framework by typetools.

the class AnnotationClassLoader method loadAnnotationClass.

/**
 * Loads the class indicated by the name, and checks to see if it is an annotation that is
 * supported by a checker.
 *
 * @param className the name of the class, in binary name format
 * @param issueError set to true to issue a warning when a loaded annotation is not a type
 *     annotation. It is useful to set this to true if a given annotation must be a well-defined
 *     type annotation (eg for annotation class names given as command line arguments). It should
 *     be set to false if the annotation is a meta-annotation or non-type annotation.
 * @return the loaded annotation class if it has a {@code @Target} meta-annotation with the
 *     required ElementType values, and is a supported annotation by a checker. If the annotation
 *     is not supported by a checker, null is returned.
 */
@Nullable
protected final Class<? extends Annotation> loadAnnotationClass(@BinaryName final String className, boolean issueError) {
    // load the class
    Class<?> cls = null;
    try {
        if (classLoader != null) {
            cls = Class.forName(className, true, classLoader);
        } else {
            cls = Class.forName(className);
        }
    } catch (ClassNotFoundException e) {
        throw new UserError(checker.getClass().getSimpleName() + ": could not load class for annotation: " + className + ". Ensure that it is a type annotation" + " and your classpath is correct.");
    }
    // return null
    if (!cls.isAnnotation()) {
        if (issueError) {
            throw new UserError(checker.getClass().getSimpleName() + ": the loaded class: " + cls.getCanonicalName() + " is not a type annotation.");
        }
        return null;
    }
    Class<? extends Annotation> annoClass = cls.asSubclass(Annotation.class);
    // ElementType values
    if (hasWellDefinedTargetMetaAnnotation(annoClass)) {
        // If so, return the loaded annotation if it is supported by a checker
        return isSupportedAnnotationClass(annoClass) ? annoClass : null;
    } else if (issueError) {
        // user expects these external annotations to be loaded.
        throw new UserError(checker.getClass().getSimpleName() + ": the loaded annotation: " + annoClass.getCanonicalName() + " is not a type annotation." + " Check its @Target meta-annotation.");
    } else {
        // in such directories.
        return null;
    }
}
Also used : UserError(org.checkerframework.javacutil.UserError) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 13 with UserError

use of org.checkerframework.javacutil.UserError in project checker-framework by typetools.

the class InitializedFieldsAnnotatedTypeFactory method createTypeFactoryForProcessor.

/**
 * Creates a new type factory for the given annotation processor, if it is a type-checker. This
 * does NOT return an existing type factory.
 *
 * @param processorName the fully-qualified class name of an annotation processor
 * @return the type factory for the given annotation processor, or null if it's not a checker
 */
GenericAnnotatedTypeFactory<?, ?, ?, ?> createTypeFactoryForProcessor(@BinaryName String processorName) {
    try {
        Class<?> checkerClass = Class.forName(processorName);
        if (!BaseTypeChecker.class.isAssignableFrom(checkerClass)) {
            return null;
        }
        @SuppressWarnings("unchecked") BaseTypeChecker c = ((Class<? extends BaseTypeChecker>) checkerClass).getDeclaredConstructor().newInstance();
        c.init(processingEnv);
        c.initChecker();
        BaseTypeVisitor<?> v = c.createSourceVisitorPublic();
        GenericAnnotatedTypeFactory<?, ?, ?, ?> atf = v.createTypeFactoryPublic();
        if (atf == null) {
            throw new UserError("Cannot find %s; check the classpath or processorpath", processorName);
        }
        return atf;
    } catch (ClassNotFoundException | InstantiationException | InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
        throw new UserError("Problem instantiating " + processorName, e);
    }
}
Also used : UserError(org.checkerframework.javacutil.UserError) BaseTypeChecker(org.checkerframework.common.basetype.BaseTypeChecker) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 14 with UserError

use of org.checkerframework.javacutil.UserError in project checker-framework by typetools.

the class SubtypingAnnotatedTypeFactory method createSupportedTypeQualifiers.

@Override
protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers() {
    // Subtyping Checker doesn't have a qual directory, so we instantiate the loader here to
    // load externally declared annotations
    loader = createAnnotationClassLoader();
    String qualNames = checker.getOption("quals");
    String qualDirectories = checker.getOption("qualDirs");
    if (qualNames == null && qualDirectories == null) {
        throw new UserError("SubtypingChecker: missing required option. Use -Aquals or -AqualDirs.");
    }
    Set<Class<? extends Annotation>> qualSet = new LinkedHashSet<>();
    // load individually named qualifiers
    if (qualNames != null) {
        for (String qualName : qualNames.split(",")) {
            if (!Signatures.isBinaryName(qualName)) {
                throw new UserError("Malformed qualifier \"%s\" in -Aquals=%s", qualName, qualNames);
            }
            Class<? extends Annotation> anno = loader.loadExternalAnnotationClass(qualName);
            if (anno == null) {
                throw new UserError("Qualifier specified in -Aquals not found: " + qualName);
            }
            qualSet.add(anno);
        }
    }
    // load directories of qualifiers
    if (qualDirectories != null) {
        for (String dirName : qualDirectories.split(":")) {
            Set<Class<? extends Annotation>> annos = loader.loadExternalAnnotationClassesFromDirectory(dirName);
            if (annos.isEmpty()) {
                throw new UserError("Directory specified in -AqualsDir contains no qualifiers: " + dirName);
            }
            qualSet.addAll(annos);
        }
    }
    if (qualSet.isEmpty()) {
        throw new UserError("SubtypingChecker: no qualifiers specified via -Aquals or -AqualDirs");
    }
    // check for subtype meta-annotation
    for (Class<? extends Annotation> qual : qualSet) {
        Annotation subtypeOfAnnotation = qual.getAnnotation(SubtypeOf.class);
        if (subtypeOfAnnotation != null) {
            for (Class<? extends Annotation> superqual : qual.getAnnotation(SubtypeOf.class).value()) {
                if (!qualSet.contains(superqual)) {
                    throw new UserError("SubtypingChecker: qualifier " + qual + " was specified via -Aquals but its super-qualifier " + superqual + " was not");
                }
            }
        }
    }
    return qualSet;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) UserError(org.checkerframework.javacutil.UserError) SubtypeOf(org.checkerframework.framework.qual.SubtypeOf) Annotation(java.lang.annotation.Annotation)

Example 15 with UserError

use of org.checkerframework.javacutil.UserError in project checker-framework by typetools.

the class SignaturePrinter method main.

public static void main(String[] args) {
    if (!(args.length == 1 && !args[0].startsWith(CHECKER_ARG)) && !(args.length == 2 && args[0].startsWith(CHECKER_ARG))) {
        printUsage();
        return;
    }
    // process arguments
    String checkerName = null;
    if (args[0].startsWith(CHECKER_ARG)) {
        checkerName = args[0].substring(CHECKER_ARG.length());
        if (!Signatures.isBinaryName(checkerName)) {
            throw new UserError("Bad checker name \"%s\"", checkerName);
        }
    }
    // Setup compiler environment
    Context context = new Context();
    JavacProcessingEnvironment env = JavacProcessingEnvironment.instance(context);
    SignaturePrinter printer = new SignaturePrinter();
    printer.init(env, checkerName);
    String className = args[args.length - 1];
    TypeElement elem = env.getElementUtils().getTypeElement(className);
    if (elem == null) {
        System.err.println("Couldn't find class: " + className);
        return;
    }
    printer.typeProcess(elem, null);
}
Also used : Context(com.sun.tools.javac.util.Context) UserError(org.checkerframework.javacutil.UserError) TypeElement(javax.lang.model.element.TypeElement) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment)

Aggregations

UserError (org.checkerframework.javacutil.UserError)16 IOException (java.io.IOException)4 JavacProcessingEnvironment (com.sun.tools.javac.processing.JavacProcessingEnvironment)3 FileWriter (java.io.FileWriter)3 Map (java.util.Map)3 Nullable (org.checkerframework.checker.nullness.qual.Nullable)3 Context (com.sun.tools.javac.util.Context)2 BufferedWriter (java.io.BufferedWriter)2 File (java.io.File)2 HashMap (java.util.HashMap)2 IdentityHashMap (java.util.IdentityHashMap)2 AnnotationMirror (javax.lang.model.element.AnnotationMirror)2 BugInCF (org.checkerframework.javacutil.BugInCF)2 TypeSystemError (org.checkerframework.javacutil.TypeSystemError)2 AScene (scenelib.annotations.el.AScene)2 ExpressionTree (com.sun.source.tree.ExpressionTree)1 VariableTree (com.sun.source.tree.VariableTree)1 Source (com.sun.tools.javac.code.Source)1 DiagnosticSource (com.sun.tools.javac.util.DiagnosticSource)1 Log (com.sun.tools.javac.util.Log)1