All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.checkerframework.framework.type.AnnotatedTypeReplacer Maven / Gradle / Ivy

Go to download

The Checker Framework enhances Java's type system to make it more powerful and useful. This lets software developers detect and prevent errors in their Java programs. The Checker Framework includes compiler plug-ins ("checkers") that find bugs or verify their absence. It also permits you to write your own compiler plug-ins.

There is a newer version: 3.43.0
Show newest version
package org.checkerframework.framework.type;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.type.TypeKind;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType;
import org.checkerframework.framework.type.visitor.DoubleAnnotatedTypeScanner;
import org.checkerframework.javacutil.BugInCF;

/**
 * Replaces or adds all the annotations in the parameter with the annotations from the visited type.
 * An annotation is replaced if the parameter type already has an annotation in the same hierarchy
 * at the same location as the visited type.
 *
 * 

Example use: * *

{@code
 * AnnotatedTypeMirror visitType = ...;
 * AnnotatedTypeMirror parameter = ...;
 * visitType.accept(new AnnotatedTypeReplacer(), parameter);
 * }
*/ public class AnnotatedTypeReplacer extends DoubleAnnotatedTypeScanner { /** * Replaces or adds all annotations from {@code from} to {@code to}. Annotations from {@code from} * will be used everywhere they exist, but annotations in {@code to} will be kept anywhere that * {@code from} is unannotated. * * @param from the annotated type mirror from which to take new annotations * @param to the annotated type mirror to which the annotations will be added * @deprecated use {@link AnnotatedTypeFactory#replaceAnnotations(AnnotatedTypeMirror, * AnnotatedTypeMirror)} instead. */ @Deprecated // 2021-03-25 @SuppressWarnings("interning:not.interned") // assertion public static void replace(final AnnotatedTypeMirror from, final AnnotatedTypeMirror to) { if (from == to) { throw new BugInCF("From == to"); } new AnnotatedTypeReplacer().visit(from, to); } /** * Replaces or adds annotations in {@code top}'s hierarchy from {@code from} to {@code to}. * Annotations from {@code from} will be used everywhere they exist, but annotations in {@code to} * will be kept anywhere that {@code from} is unannotated. * * @param from the annotated type mirror from which to take new annotations * @param to the annotated type mirror to which the annotations will be added * @param top the top type of the hierarchy whose annotations will be added * @deprecated use {@link AnnotatedTypeFactory#replaceAnnotations(AnnotatedTypeMirror, * AnnotatedTypeMirror, AnnotationMirror)} instead. */ @Deprecated // 2021-03-25 @SuppressWarnings("interning:not.interned") // assertion public static void replace( final AnnotatedTypeMirror from, final AnnotatedTypeMirror to, final AnnotationMirror top) { if (from == to) { throw new BugInCF("from == to: %s", from); } new AnnotatedTypeReplacer(top).visit(from, to); } /** If top != null we replace only the annotations in the hierarchy of top. */ private AnnotationMirror top; /** Construct an AnnotatedTypeReplacer that will replace all annotations. */ public AnnotatedTypeReplacer() { this.top = null; } /** * Construct an AnnotatedTypeReplacer that will only replace annotations in {@code top}'s * hierarchy. * * @param top if top != null, then only annotation in the hierarchy of top are affected */ public AnnotatedTypeReplacer(final AnnotationMirror top) { this.top = top; } /** * If {@code top != null}, then only annotations in the hierarchy of {@code top} are affected; * otherwise, all annotations are replaced. * * @param top if top != null, then only annotations in the hierarchy of top are replaced; * otherwise, all annotations are replaced. */ public void setTop(@Nullable AnnotationMirror top) { this.top = top; } @SuppressWarnings("interning:not.interned") // assertion @Override protected Void defaultAction(AnnotatedTypeMirror from, AnnotatedTypeMirror to) { assert from != to; if (from != null && to != null) { replaceAnnotations(from, to); } return null; } /** * Replace the annotations in to with the annotations in from, wherever from has an annotation. * * @param from the source of the annotations * @param to the destination of the annotations, modified by this method */ protected void replaceAnnotations(final AnnotatedTypeMirror from, final AnnotatedTypeMirror to) { if (top == null) { to.replaceAnnotations(from.getAnnotations()); } else { final AnnotationMirror replacement = from.getAnnotationInHierarchy(top); if (replacement != null) { to.replaceAnnotation(from.getAnnotationInHierarchy(top)); } } } @Override public Void visitTypeVariable(AnnotatedTypeVariable from, AnnotatedTypeMirror to) { resolvePrimaries(from, to); return super.visitTypeVariable(from, to); } @Override public Void visitWildcard(AnnotatedWildcardType from, AnnotatedTypeMirror to) { resolvePrimaries(from, to); return super.visitWildcard(from, to); } /** * For type variables and wildcards, the absence of a primary annotations has an implied meaning * on substitution. Therefore, in these cases we remove the primary annotation and rely on the * fact that the bounds are also merged into the type to. * * @param from a type variable or wildcard * @param to the destination annotated type mirror */ public void resolvePrimaries(AnnotatedTypeMirror from, AnnotatedTypeMirror to) { if (from.getKind() == TypeKind.WILDCARD || from.getKind() == TypeKind.TYPEVAR) { if (top != null) { if (from.getAnnotationInHierarchy(top) == null) { to.removeAnnotationInHierarchy(top); } } else { for (final AnnotationMirror toPrimaryAnno : to.getAnnotations()) { if (from.getAnnotationInHierarchy(toPrimaryAnno) == null) { to.removeAnnotation(toPrimaryAnno); } } } } else { throw new BugInCF( "ResolvePrimaries's from argument should be a type variable OR wildcard%n" + "from=%s%nto=%s", from.toString(true), to.toString(true)); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy