@Override
    public Void visitBinary(BinaryTree node, AnnotatedTypeMirror p) {

      if (!p.isAnnotated() && checker.isChecking()) {
        p.addAnnotation(checker.BOTTOM);
      }

      return super.visitBinary(node, p);
    }
 @Override
 public Void visitVariable(VariableTree node, AnnotatedTypeMirror p) {
   typeAnnotator.visit(p);
   VariableElement varElt = TreeUtils.elementFromDeclaration((VariableTree) node);
   if (!p.isAnnotated() && ElementUtils.isStatic(varElt)) {
     p.clearAnnotations();
     Set<AnnotationMirror> set = AnnotationUtils.createAnnotationSet();
     set.add(checker.ANY);
     set.add(checker.PEER);
     annotateConstants(p, set);
   }
   return super.visitVariable(node, p);
 }
 @Override
 public Void visitLiteral(LiteralTree tree, AnnotatedTypeMirror type) {
   if (!type.isAnnotated()) {
     //				if (type.getKind() == TypeKind.NULL) {
     type.clearAnnotations();
     Set<AnnotationMirror> set = AnnotationUtils.createAnnotationSet();
     set.add(checker.BOTTOM);
     annotateConstants(type, set);
     //				}
     //				else
     //					type.addAnnotation(checker.READONLY);
   }
   return super.visitLiteral(tree, type);
 }
Exemplo n.º 4
0
 @Override
 public final boolean isSubtype(AnnotatedTypeMirror rhs, AnnotatedTypeMirror lhs) {
   if (lhs.getKind() == TypeKind.TYPEVAR && rhs.getKind() == TypeKind.TYPEVAR) {
     // TODO: Investigate whether there is a nicer and more proper way to
     // get assignments between two type variables working.
     if (lhs.getAnnotations().isEmpty()) {
       return true;
     }
   }
   // Otherwise Covariant would cause trouble.
   if (rhs.hasAnnotation(KeyForBottom.class)) {
     return true;
   }
   return super.isSubtype(rhs, lhs);
 }
  @Override
  public boolean isAssignable(AnnotatedTypeMirror varType, Tree varTree) {
    if (varTree.getKind() == Tree.Kind.VARIABLE || varType.hasAnnotation(ASSIGNABLE)) return true;

    Element varElement = InternalUtils.symbol(varTree);
    if (varElement == null || !varElement.getKind().isField() || ElementUtils.isStatic(varElement))
      return true;

    ExpressionTree expTree = (ExpressionTree) varTree;
    AnnotatedTypeMirror receiver = factory.getReceiver(expTree);

    boolean isAssignable =
        receiver.hasAnnotation(MUTABLE)
            || (receiver.hasAnnotation(ASSIGNS_FIELDS) && TreeUtils.isSelfAccess(expTree));

    return isAssignable;
  }
    @Override
    public Void visitLiteral(LiteralTree tree, AnnotatedTypeMirror type) {
      if (!type.isAnnotated()) {

        if (factory.getVisitorState().getAssignmentContext().getExplicitAnnotations().size() > 0) {

          for (AnnotationMirror m :
              factory.getVisitorState().getAssignmentContext().getExplicitAnnotations()) {

            type.addAnnotation(m);
            break;
          }
        }

        // type.atypeFactory.getVisitorState().getAssignmentContext().getExplicitAnnotations().size();
        //
        //                System.out.println("Visiting unannotated type~\n\n");
        //
        //                AnnotationBuilder builder =
        //                        new AnnotationBuilder(processingEnv,
        // Level.class.getCanonicalName());
        //                builder.setValue("value", "Public");
        //
        ////                type.addAnnotation(builder.build());
        //
        //                String regex = null;
        ////                   if (tree.getKind() == Tree.Kind.STRING_LITERAL) {
        ////                       regex = (String) tree.getValue();
        ////                   } else if (tree.getKind() == Tree.Kind.CHAR_LITERAL) {
        ////                       regex = Character.toString((Character) tree.getValue());
        ////                   }
        ////                   if (regex != null) {
        ////                       if (isRegex(regex)) {
        ////                           int groupCount = checker.getGroupCount(regex);
        ////                           type.addAnnotation(createRegexAnnotation(groupCount));
        ////                       } else {
        ////                           type.addAnnotation(createPartialRegexAnnotation(regex));
        ////                       }
        ////                   }
      }
      return super.visitLiteral(tree, type);
    }
 @Override
 public AnnotatedTypeMirror getAnnotatedType(Tree tree) {
   AnnotatedTypeMirror type = super.getAnnotatedType(tree);
   if (tree instanceof ExpressionTree) tree = TreeUtils.skipParens((ExpressionTree) tree);
   Element elt = InternalUtils.symbol(tree);
   if (!checker.isChecking() /*&& !checker.isDefaultAnyType(type)*/
       && type.isAnnotated()
       && !type.getKind().isPrimitive()
       && type.getKind() != TypeKind.NULL
       && (elt == null || !ElementUtils.isStatic(elt))) {
     // We don't want annotations on the following trees
     Kind kind = tree.getKind();
     if (kind == Kind.METHOD_INVOCATION
         || kind == Kind.ARRAY_ACCESS
         || kind == Kind.MEMBER_SELECT
         || kind == Kind.CONDITIONAL_EXPRESSION) {
       type = type.getCopy(false);
     }
   }
   return type;
 }
    @Override
    public Void visitTypeCast(TypeCastTree node, AnnotatedTypeMirror p) {

      if (!p.isAnnotated()) {
        // check if it is casting "this"
        if (TreeUtils.skipParens(node.getExpression()).toString().equals("this")) {
          annotateThis(p);
        }
      }

      return super.visitTypeCast(node, p);
    }
  /** Tests whether t1 is a subtype of t2, with respect to IGJ Subtyping rules */
  @Override
  public boolean isSubtype(AnnotatedTypeMirror sup, AnnotatedTypeMirror sub) {
    // TODO: Check that they are up to the same base
    // Err... cannot handle type variables quite yet
    if (sup.getKind() == TypeKind.TYPEVAR
        || sup.getKind() == TypeKind.WILDCARD
        || sub.getKind() == TypeKind.TYPEVAR
        || sub.getKind() == TypeKind.WILDCARD) return true;

    AnnotatedTypes annoUtils = new AnnotatedTypes(env, factory);

    AnnotatedTypeMirror valueBaseType = annoUtils.asSuper(sub, sup);
    if (valueBaseType == null)
      // For now
      valueBaseType = sub;

    boolean isSubtype = isSubtypeOneLevel(sup, valueBaseType);
    boolean typeArgShouldBeSame = sup.hasAnnotation(MUTABLE);

    if ((sup.getKind() == TypeKind.DECLARED) && (valueBaseType.getKind() == TypeKind.DECLARED)) {
      AnnotatedDeclaredType supDecl = (AnnotatedDeclaredType) sup;
      AnnotatedDeclaredType subDecl = (AnnotatedDeclaredType) valueBaseType;

      //            if (supDecl.getTypeArguments().size() != subDecl.getTypeArguments().size())
      //                System.out.println("Investigate this " + supDecl + " " + subDecl);

      for (int i = 0;
          i < supDecl.getTypeArguments().size() && i < subDecl.getTypeArguments().size();
          ++i) {
        AnnotatedTypeMirror supArg = supDecl.getTypeArguments().get(i);
        AnnotatedTypeMirror subArg = subDecl.getTypeArguments().get(i);
        if (typeArgShouldBeSame) isSubtype &= isSameImmutability(supArg, subArg);
        else isSubtype &= isSubtype(supArg, subArg);
      }
    } else if ((sup.getKind() == TypeKind.ARRAY) && (valueBaseType.getKind() == TypeKind.ARRAY)) {
      AnnotatedArrayType supArr = (AnnotatedArrayType) sup;
      AnnotatedArrayType subArr = (AnnotatedArrayType) valueBaseType;
      if (typeArgShouldBeSame)
        isSubtype &= isSameImmutability(supArr.getComponentType(), subArr.getComponentType());
      else isSubtype &= isSubtype(supArr.getComponentType(), subArr.getComponentType());
    }

    return isSubtype;
  }
Exemplo n.º 10
0
 @Override
 public R visitTypeVariable(AnnotatedTypeVariable type, AnnotatedTypeMirror p) {
   // assert p instanceof AnnotatedTypeVariable : p;
   R r;
   if (visitedNodes.containsKey(type)) {
     return visitedNodes.get(type);
   }
   if (p instanceof AnnotatedTypeVariable) {
     AnnotatedTypeVariable tv = (AnnotatedTypeVariable) p;
     r = scan(type.getLowerBound(), tv.getLowerBound());
     visitedNodes.put(type, r);
     r = scanAndReduce(type.getUpperBound(), tv.getUpperBound(), r);
     visitedNodes.put(type, r);
   } else {
     r = scan(type.getLowerBound(), p.getErased());
     visitedNodes.put(type, r);
     r = scanAndReduce(type.getUpperBound(), p, r);
     visitedNodes.put(type, r);
   }
   return r;
 }
 @Override
 public boolean isValidUse(AnnotatedTypeMirror elemType, AnnotatedTypeMirror use) {
   if (elemType.hasAnnotation(I) || use.hasAnnotation(READONLY)) return true;
   else return super.isValidUse(elemType, use);
 }
  public boolean isSubtypeOneLevel(AnnotatedTypeMirror sup, AnnotatedTypeMirror sub) {
    // Current implementation only need to deal with one level
    // Err... cannot handle type variables quite yet
    if (sup.getKind() == TypeKind.TYPEVAR
        || sup.getKind() == TypeKind.WILDCARD
        || sub.getKind() == TypeKind.TYPEVAR
        || sub.getKind() == TypeKind.WILDCARD) return true;

    // TODO: Need to handle Generics and Arrays
    if (sup.hasAnnotation(READONLY)
        || sup.hasAnnotation(PLACE_HOLDER)
        || sub.hasAnnotation(PLACE_HOLDER)) return true;
    else if (sup.hasAnnotation(I)) {
      // t1 is a subtype of t2, if and only they have the same
      // immutability argument
      if (!sub.hasAnnotation(I)) return false;

      AnnotationUtils annoUtils = new AnnotationUtils(this.env);
      String t1Arg =
          annoUtils.parseStringValue(
              sub.getAnnotation(I.class.getCanonicalName()), IMMUTABILITY_KEY);
      String t2Arg =
          annoUtils.parseStringValue(
              sup.getAnnotation(I.class.getCanonicalName()), IMMUTABILITY_KEY);

      return ((t1Arg != null) && (t2Arg != null) && t1Arg.equals(t2Arg));
    }

    return ((sup.hasAnnotation(IMMUTABLE) && sub.hasAnnotation(IMMUTABLE))
        || (sup.hasAnnotation(MUTABLE) && sub.hasAnnotation(MUTABLE))
        || (sup.hasAnnotation(ASSIGNS_FIELDS) && sub.hasAnnotation(ASSIGNS_FIELDS))
        || (sup.hasAnnotation(ASSIGNS_FIELDS) && sub.hasAnnotation(MUTABLE)));
  }
  public boolean isSameImmutability(AnnotatedTypeMirror sup, AnnotatedTypeMirror sub) {
    // Err... cannot handle type variables quite yet
    if (sup.getKind() == TypeKind.TYPEVAR
        || sup.getKind() == TypeKind.WILDCARD
        || sub.getKind() == TypeKind.TYPEVAR
        || sub.getKind() == TypeKind.WILDCARD) return true;

    if (sup.hasAnnotation(PLACE_HOLDER) || sub.hasAnnotation(PLACE_HOLDER)) return true;
    else if (sup.hasAnnotation(READONLY)) return sub.hasAnnotation(READONLY);
    else if (sup.hasAnnotation(MUTABLE)) return sub.hasAnnotation(MUTABLE);
    else if (sup.hasAnnotation(IMMUTABLE)) return sub.hasAnnotation(IMMUTABLE);

    return false;
  }
 private void annotateThis(AnnotatedTypeMirror type) {
   if (checker.isChecking()) return;
   type.clearAnnotations();
   type.addAnnotation(checker.SELF);
 }