blob: c47c8b87cb8b7a8d79486f47b3001b4d3505064b [file] [log] [blame]
package org.checkerframework.checker.i18n;
import com.sun.source.tree.BinaryTree;
import com.sun.source.tree.CompoundAssignmentTree;
import com.sun.source.tree.LiteralTree;
import com.sun.source.tree.Tree;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.lang.model.element.AnnotationMirror;
import org.checkerframework.checker.i18n.qual.Localized;
import org.checkerframework.checker.i18n.qual.UnknownLocalized;
import org.checkerframework.common.basetype.BaseAnnotatedTypeFactory;
import org.checkerframework.common.basetype.BaseTypeChecker;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.treeannotator.ListTreeAnnotator;
import org.checkerframework.framework.type.treeannotator.TreeAnnotator;
import org.checkerframework.javacutil.AnnotationBuilder;
public class I18nAnnotatedTypeFactory extends BaseAnnotatedTypeFactory {
public I18nAnnotatedTypeFactory(BaseTypeChecker checker) {
super(checker);
this.postInit();
}
@Override
protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers() {
return new LinkedHashSet<>(Arrays.asList(Localized.class, UnknownLocalized.class));
}
@Override
protected TreeAnnotator createTreeAnnotator() {
return new ListTreeAnnotator(super.createTreeAnnotator(), new I18nTreeAnnotator(this));
}
/** Do not propagate types through binary/compound operations. */
private class I18nTreeAnnotator extends TreeAnnotator {
/** The @{@link Localized} annotation. */
private final AnnotationMirror LOCALIZED =
AnnotationBuilder.fromClass(elements, Localized.class);
public I18nTreeAnnotator(AnnotatedTypeFactory atypeFactory) {
super(atypeFactory);
}
@Override
public Void visitBinary(BinaryTree tree, AnnotatedTypeMirror type) {
type.removeAnnotation(LOCALIZED);
return null;
}
@Override
public Void visitCompoundAssignment(CompoundAssignmentTree node, AnnotatedTypeMirror type) {
type.removeAnnotation(LOCALIZED);
return null;
}
@Override
public Void visitLiteral(LiteralTree tree, AnnotatedTypeMirror type) {
if (!type.isAnnotatedInHierarchy(LOCALIZED)) {
if (tree.getKind() == Tree.Kind.STRING_LITERAL && tree.getValue().equals("")) {
type.addAnnotation(LOCALIZED);
}
}
return super.visitLiteral(tree, type);
}
}
}