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

framework.src.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.42.0
Show newest version
package org.checkerframework.framework.type;

import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable;
import java.util.IdentityHashMap;
import java.util.Map;

/**
 * Duplicates annotated types and replaces components according to a replacement map.
 */
public class AnnotatedTypeReplacer {

    /**
     * Return a copy of type after making the specified replacements.
     * @param type the type that will be copied with replaced components
     * @param replacementMap a mapping of {@literal referenceToReplace -> referenceOfReplacement}
     * @return a duplicate of type in which every reference that was a key in replacementMap
     * has been replaced by its corresponding value
     */
    public static AnnotatedTypeMirror replace(
            AnnotatedTypeMirror type,
            Map replacementMap) {
        return new Visitor(replacementMap).visit(type);
    }

    /**
     * AnnotatedTypeCopier maintains a mapping of {@literal typeVisited -> copyOfTypeVisited}
     * When a reference, typeVisited, is encountered again, it will use the recorded reference,
     * copyOfTypeVisited, instead of generating a new copy of typeVisited.  Visitor pre-populates
     * this mapping so that references are replaced not by their copies but by those in the
     * replacementMap provided in the constructor.
     *
     * All types NOT in the replacement map are duplicated as per AnnotatedTypeCopier.visit
     */
    protected static class Visitor extends AnnotatedTypeCopier {

        private final IdentityHashMap originalMappings;

        public Visitor(final Map mappings) {
            originalMappings = new IdentityHashMap<>(mappings);
        }

        @Override
        public AnnotatedTypeMirror visit(AnnotatedTypeMirror type) {
            return type.accept(this, new IdentityHashMap<>(originalMappings));
        }

        public AnnotatedTypeMirror visitTypeVariable(AnnotatedTypeVariable original, IdentityHashMap originalToCopy) {
            // AnnotatedTypeCopier will visit the type parameters of a method and copy them
            // Without this flag, any mappings in originalToCopy would replace the type parameters.
            // However, we do not replace the type parameters in an AnnotatedExecutableType.  Also,
            // AnnotatedExecutableType.typeVarTypes is of type List so if
            // the mapping contained a type parameter -> (Non-type variable AnnotatedTypeMirror) then
            // a runtime exception would occur.
            if (visitingExecutableTypeParam) {
                visitingExecutableTypeParam = false;
                final AnnotatedTypeVariable copy = (AnnotatedTypeVariable) AnnotatedTypeMirror.createType(
                        original.getUnderlyingType(), original.atypeFactory, original.isDeclaration());
                maybeCopyPrimaryAnnotations(original, copy);
                originalToCopy.put(original, copy);

                if (original.getUpperBoundField() != null) {
                    copy.setUpperBoundField(visit(original.getUpperBoundField(), originalToCopy));
                }

                if (original.getLowerBoundField() != null) {
                    copy.setLowerBoundField(visit(original.getLowerBoundField(), originalToCopy));
                }
                return copy;

            }

            return super.visitTypeVariable(original, originalToCopy);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy