Search in sources :

Example 1 with TypeCastTree

use of org.sonar.plugins.java.api.tree.TypeCastTree in project sonar-java by SonarSource.

the class CFG method buildTypeCast.

private void buildTypeCast(Tree tree) {
    enclosingTry.peek().catches.entrySet().stream().filter(e -> e.getKey().isSubtypeOf("java.lang.ClassCastException")).findFirst().ifPresent(e -> {
        currentBlock = createBlock(currentBlock);
        currentBlock.successors.add(e.getValue());
    });
    currentBlock.elements.add(tree);
    TypeCastTree typeCastTree = (TypeCastTree) tree;
    build(typeCastTree.expression());
}
Also used : TypeCastTree(org.sonar.plugins.java.api.tree.TypeCastTree)

Example 2 with TypeCastTree

use of org.sonar.plugins.java.api.tree.TypeCastTree in project sonar-java by SonarSource.

the class JavaTreeModelTest method type_cast.

/**
 * 15.16. Cast Expressions
 */
@Test
public void type_cast() {
    TypeCastTree tree = (TypeCastTree) expressionOfReturnStatement("class T { boolean m() { return (Boolean) true; } }");
    assertThat(tree.is(Tree.Kind.TYPE_CAST)).isTrue();
    assertThat(tree.openParenToken().text()).isEqualTo("(");
    assertThat(tree.type()).isNotNull();
    assertThat(tree.closeParenToken().text()).isEqualTo(")");
    assertThat(tree.expression()).isNotNull();
    assertThatChildrenIteratorHasSize(tree, 5);
    tree = (TypeCastTree) expressionOfReturnStatement("class T { boolean m() { return (Foo<T> & Bar) true; } }");
    assertThat(tree.is(Tree.Kind.TYPE_CAST)).isTrue();
    assertThat(tree.openParenToken().text()).isEqualTo("(");
    assertThat(tree.type()).isNotNull();
    assertThat(tree.andToken()).isNotNull();
    assertThat(tree.bounds()).hasSize(1);
    assertThat(tree.closeParenToken().text()).isEqualTo(")");
    assertThat(tree.expression()).isNotNull();
    assertThatChildrenIteratorHasSize(tree, 6);
    tree = (TypeCastTree) expressionOfReturnStatement("class T { boolean m() { return (Foo<T> & @Gul Bar) true; } }");
    assertThat(tree.is(Tree.Kind.TYPE_CAST)).isTrue();
    assertThat(tree.openParenToken().text()).isEqualTo("(");
    assertThat(tree.type()).isNotNull();
    assertThat(tree.andToken()).isNotNull();
    assertThat(tree.bounds()).hasSize(1);
    assertThat(tree.bounds().separators()).isEmpty();
    assertThat(tree.closeParenToken().text()).isEqualTo(")");
    assertThat(tree.expression()).isNotNull();
    assertThatChildrenIteratorHasSize(tree, 6);
    tree = (TypeCastTree) expressionOfReturnStatement("class T { boolean m() { return (Foo<T> & @Gul Bar & Qix & Plop) true; } }");
    assertThat(tree.is(Tree.Kind.TYPE_CAST)).isTrue();
    assertThat(tree.openParenToken().text()).isEqualTo("(");
    assertThat(tree.type()).isNotNull();
    assertThat(tree.andToken()).isNotNull();
    assertThat(tree.bounds()).hasSize(3);
    assertThat(tree.bounds().separators()).hasSize(2);
    assertThat(tree.closeParenToken().text()).isEqualTo(")");
    assertThat(tree.expression()).isNotNull();
    assertThatChildrenIteratorHasSize(tree, 6);
}
Also used : TypeCastTree(org.sonar.plugins.java.api.tree.TypeCastTree) Test(org.junit.Test)

Example 3 with TypeCastTree

use of org.sonar.plugins.java.api.tree.TypeCastTree in project sonar-java by SonarSource.

the class JavaTreeModelTest method annotations.

@Test
public void annotations() {
    ClassTree tree = firstType("@SuppressWarnings(\"unchecked\") class T { }");
    List<AnnotationTree> annotations = tree.modifiers().annotations();
    assertThat(annotations).hasSize(1);
    AnnotationTree annotation = annotations.get(0);
    assertThat(annotation.annotationType().is(Tree.Kind.IDENTIFIER)).isTrue();
    assertThat(annotation.arguments().openParenToken()).isNotNull();
    assertThat(annotation.arguments().separators()).isEmpty();
    assertThat(annotation.arguments()).hasSize(1);
    assertThat(annotation.arguments().get(0).is(Tree.Kind.STRING_LITERAL)).isTrue();
    assertThat(annotation.arguments().closeParenToken()).isNotNull();
    assertThat(annotation.atToken()).isNotNull();
    assertThatChildrenIteratorHasSize(annotation, 3);
    tree = firstType("@Target( ) class U {}");
    annotations = tree.modifiers().annotations();
    assertThat(annotations).hasSize(1);
    annotation = annotations.get(0);
    assertThat(annotation.arguments().openParenToken()).isNotNull();
    assertThat(annotation.arguments()).isEmpty();
    assertThat(annotation.arguments().separators()).isEmpty();
    assertThat(annotation.arguments().closeParenToken()).isNotNull();
    assertThat(annotation.atToken()).isNotNull();
    assertThatChildrenIteratorHasSize(annotation, 3);
    tree = firstType("@Target({ElementType.METHOD}) class U {}");
    annotations = tree.modifiers().annotations();
    assertThat(annotations).hasSize(1);
    annotation = annotations.get(0);
    assertThat(annotation.arguments().openParenToken()).isNotNull();
    assertThat(annotation.arguments()).hasSize(1);
    assertThat(annotation.arguments().get(0).is(Tree.Kind.NEW_ARRAY)).isTrue();
    assertThat(annotation.arguments().separators()).isEmpty();
    assertThat(annotation.arguments().closeParenToken()).isNotNull();
    assertThat(annotation.atToken()).isNotNull();
    assertThatChildrenIteratorHasSize(annotation, 3);
    tree = firstType("@SuppressWarnings({\"hello\",}) class U {}");
    annotations = tree.modifiers().annotations();
    assertThat(annotations).hasSize(1);
    annotation = annotations.get(0);
    assertThat(annotation.arguments().openParenToken()).isNotNull();
    assertThat(annotation.arguments()).hasSize(1);
    assertThat(annotation.arguments().get(0).is(Tree.Kind.NEW_ARRAY)).isTrue();
    NewArrayTree arg = (NewArrayTree) annotation.arguments().get(0);
    assertThat(arg.initializers()).hasSize(1);
    assertThat(arg.initializers().get(0).is(Tree.Kind.STRING_LITERAL)).isTrue();
    assertThat(arg.initializers().separators()).hasSize(1);
    assertThat(annotation.arguments().closeParenToken()).isNotNull();
    assertThat(annotation.atToken()).isNotNull();
    assertThatChildrenIteratorHasSize(annotation, 3);
    tree = firstType("@Target(value={ElementType.METHOD}, value2=\"toto\") class T { }");
    annotations = tree.modifiers().annotations();
    assertThat(annotations).hasSize(1);
    annotation = annotations.get(0);
    assertThat(annotation.annotationType().is(Tree.Kind.IDENTIFIER)).isTrue();
    assertThat(annotation.arguments().openParenToken()).isNotNull();
    assertThat(annotation.arguments()).hasSize(2);
    assertThat(annotation.arguments().separators()).hasSize(1);
    assertThat(annotation.arguments().get(0).is(Tree.Kind.ASSIGNMENT)).isTrue();
    assertThat(annotation.arguments().closeParenToken()).isNotNull();
    assertThat(annotation.atToken()).isNotNull();
    assertThatChildrenIteratorHasSize(annotation, 3);
    VariableTree variable = (VariableTree) firstMethodFirstStatement("class T { private void meth() { @NonNullable String str;}}");
    assertThatChildrenIteratorHasSize(variable, 4);
    annotations = variable.modifiers().annotations();
    assertThat(annotations).hasSize(1);
    annotation = annotations.get(0);
    assertThat(annotation.annotationType().is(Tree.Kind.IDENTIFIER)).isTrue();
    assertThat(annotation.atToken()).isNotNull();
    assertThat(annotation.arguments()).isEmpty();
    assertThatChildrenIteratorHasSize(annotation, 3);
    annotations = compilationUnit("@PackageLevelAnnotation package blammy;").packageDeclaration().annotations();
    assertThat(annotations).hasSize(1);
    assertThat(annotations.get(0).atToken()).isNotNull();
    assertThat(annotation.arguments()).isEmpty();
    assertThatChildrenIteratorHasSize(annotation, 3);
    variable = (VariableTree) firstMethodFirstStatement("class T { private void m() { @Foo Integer foo; } }");
    assertThat(variable.modifiers().annotations()).hasSize(1);
    assertThat(variable.type().is(Tree.Kind.IDENTIFIER)).isTrue();
    assertThat(variable.type().annotations()).isEmpty();
    assertThatChildrenIteratorHasSize(variable, 4);
    variable = (VariableTree) firstMethodFirstStatement("class T { private void m() { @Foo java.lang.Integer foo; } }");
    assertThat(variable.modifiers().annotations()).hasSize(1);
    assertThat(variable.type().is(Tree.Kind.MEMBER_SELECT)).isTrue();
    assertThat(variable.type().annotations()).isEmpty();
    assertThatChildrenIteratorHasSize(variable, 4);
    variable = (VariableTree) firstMethodFirstStatement("class T { private void m() { java.lang.@Foo Integer foo; } }");
    assertThat(variable.modifiers()).isEmpty();
    assertThat(variable.type().is(Tree.Kind.MEMBER_SELECT)).isTrue();
    assertThat(variable.type().annotations()).isEmpty();
    assertThatChildrenIteratorHasSize(variable, 4);
    assertThat(((MemberSelectExpressionTree) variable.type()).identifier().annotations()).hasSize(1);
    variable = (VariableTree) firstMethodFirstStatement("class T { private void m() { a.B.C foo = a.B.new @Foo C(); } }");
    assertThat(variable.modifiers()).isEmpty();
    assertThatChildrenIteratorHasSize(variable, 6);
    TypeTree type = ((NewClassTree) variable.initializer()).identifier();
    assertThat(type.is(Tree.Kind.IDENTIFIER)).isTrue();
    assertThat(type.annotations()).hasSize(1);
    assertThatChildrenIteratorHasSize(type, 2);
    variable = (VariableTree) firstMethodFirstStatement("class T { private void m() { a.b.C<Integer> foo = a.B.new @Foo C<Integer>(); } }");
    assertThat(variable.modifiers()).isEmpty();
    assertThatChildrenIteratorHasSize(variable, 6);
    type = ((NewClassTree) variable.initializer()).identifier();
    assertThat(type.is(Tree.Kind.PARAMETERIZED_TYPE)).isTrue();
    assertThat(type.annotations()).hasSize(1);
    assertThatChildrenIteratorHasSize(type, 3);
    variable = (VariableTree) firstMethodFirstStatement("class T { private void m() { a.B.C foo = new @Foo a.B.C(); } }");
    assertThat(variable.modifiers()).isEmpty();
    assertThatChildrenIteratorHasSize(variable, 6);
    type = ((NewClassTree) variable.initializer()).identifier();
    assertThat(type.is(Tree.Kind.MEMBER_SELECT)).isTrue();
    assertThat(type.annotations()).hasSize(1);
    assertThatChildrenIteratorHasSize(type, 4);
    variable = (VariableTree) firstMethodFirstStatement("class T { private void m() { a.b.C<Integer> foo = new @Foo a.b.C<Integer>(); } }");
    assertThat(variable.modifiers()).isEmpty();
    assertThatChildrenIteratorHasSize(variable, 6);
    type = ((NewClassTree) variable.initializer()).identifier();
    assertThat(type.is(Tree.Kind.PARAMETERIZED_TYPE)).isTrue();
    assertThat(type.annotations()).hasSize(1);
    assertThatChildrenIteratorHasSize(type, 3);
    variable = (VariableTree) firstMethodFirstStatement("class T { private void m() { int[] foo = new @Foo int[42]; } }");
    assertThat(variable.modifiers()).isEmpty();
    assertThatChildrenIteratorHasSize(variable, 6);
    type = ((NewArrayTree) variable.initializer()).type();
    assertThat(type.is(Tree.Kind.PRIMITIVE_TYPE)).isTrue();
    assertThat(type.annotations()).hasSize(1);
    assertThatChildrenIteratorHasSize(type, 2);
    variable = ((TryStatementTree) firstMethodFirstStatement("class T { private void m() { try{ } catch (@Foo E1 | E2 e) {}; } }")).catches().get(0).parameter();
    assertThat(variable.modifiers()).hasSize(1);
    assertThatChildrenIteratorHasSize(variable, 3);
    type = variable.type();
    assertThat(type.is(Tree.Kind.UNION_TYPE)).isTrue();
    assertThat(type.annotations()).isEmpty();
    assertThat(((UnionTypeTree) type).typeAlternatives().separators()).hasSize(1);
    assertThatChildrenIteratorHasSize(type, 1);
    ClassTree classTree = firstType("class T extends @Foo a.b.C {}");
    assertThat(classTree.modifiers()).isEmpty();
    assertThatChildrenIteratorHasSize(classTree, 9);
    type = classTree.superClass();
    assertThat(type.is(Tree.Kind.MEMBER_SELECT)).isTrue();
    assertThat(type.annotations()).hasSize(1);
    assertThatChildrenIteratorHasSize(type, 4);
    classTree = firstType("class T extends @Foo a.b.C<Integer> {}");
    assertThat(classTree.modifiers()).isEmpty();
    assertThatChildrenIteratorHasSize(classTree, 9);
    type = classTree.superClass();
    assertThat(type.is(Tree.Kind.PARAMETERIZED_TYPE)).isTrue();
    assertThat(type.annotations()).hasSize(1);
    assertThatChildrenIteratorHasSize(type, 3);
    classTree = (ClassTree) firstMethodFirstStatement("class MyClass<A, B, C> { void foo() { class MyOtherClass extends @Foo MyClass<A, B, C>.MyInnerClass {} } public class MyInnerClass {}}");
    assertThat(classTree.modifiers()).isEmpty();
    assertThatChildrenIteratorHasSize(classTree, 9);
    type = classTree.superClass();
    assertThat(type.is(Tree.Kind.MEMBER_SELECT)).isTrue();
    assertThat(type.annotations()).hasSize(1);
    type = (ParameterizedTypeTree) ((MemberSelectExpressionTree) type).expression();
    assertThat(type.is(Tree.Kind.PARAMETERIZED_TYPE)).isTrue();
    assertThat(type.annotations()).hasSize(0);
    assertThatChildrenIteratorHasSize(type, 2);
    TypeCastTree typeCast = (TypeCastTree) ((ReturnStatementTree) firstMethodFirstStatement("class T { private long m(int a) { return (@Foo long) a; } }")).expression();
    assertThat(typeCast.type()).isNotNull();
    assertThatChildrenIteratorHasSize(typeCast, 5);
    type = typeCast.type();
    assertThat(type.is(Tree.Kind.PRIMITIVE_TYPE)).isTrue();
    assertThat(type.annotations()).hasSize(1);
    assertThatChildrenIteratorHasSize(type, 2);
}
Also used : TypeCastTree(org.sonar.plugins.java.api.tree.TypeCastTree) UnionTypeTree(org.sonar.plugins.java.api.tree.UnionTypeTree) ArrayTypeTree(org.sonar.plugins.java.api.tree.ArrayTypeTree) TypeTree(org.sonar.plugins.java.api.tree.TypeTree) ParameterizedTypeTree(org.sonar.plugins.java.api.tree.ParameterizedTypeTree) PrimitiveTypeTree(org.sonar.plugins.java.api.tree.PrimitiveTypeTree) MemberSelectExpressionTree(org.sonar.plugins.java.api.tree.MemberSelectExpressionTree) NewArrayTree(org.sonar.plugins.java.api.tree.NewArrayTree) NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree) ClassTree(org.sonar.plugins.java.api.tree.ClassTree) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) AnnotationTree(org.sonar.plugins.java.api.tree.AnnotationTree) NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree) Test(org.junit.Test)

Example 4 with TypeCastTree

use of org.sonar.plugins.java.api.tree.TypeCastTree in project sonar-java by SonarSource.

the class RedundantTypeCastCheck method targetType.

@CheckForNull
private static Type targetType(TypeCastTree tree) {
    Tree parent = skipParentheses(tree.parent());
    Type target = null;
    if (parent.is(Tree.Kind.RETURN_STATEMENT)) {
        Tree method = parent;
        while (!method.is(Tree.Kind.METHOD, Tree.Kind.LAMBDA_EXPRESSION)) {
            method = method.parent();
        }
        target = method.is(Tree.Kind.LAMBDA_EXPRESSION) ? null : ((MethodJavaType) ((MethodTree) method).symbol().type()).resultType();
    } else if (parent.is(Tree.Kind.VARIABLE)) {
        VariableTree variableTree = (VariableTree) parent;
        target = variableTree.symbol().type();
    } else if (parent.is(Tree.Kind.METHOD_INVOCATION)) {
        MethodInvocationTree mit = (MethodInvocationTree) parent;
        if (mit.symbol().isMethodSymbol()) {
            JavaSymbol.MethodJavaSymbol sym = (JavaSymbol.MethodJavaSymbol) mit.symbol();
            int castArgIndex = mit.arguments().indexOf(tree);
            target = sym.parameterTypes().get(castArgIndex);
        }
    } else if (parent.is(Tree.Kind.MEMBER_SELECT, Tree.Kind.CONDITIONAL_EXPRESSION)) {
        target = tree.type().symbolType();
    } else if (parent.is(Tree.Kind.ARRAY_ACCESS_EXPRESSION)) {
        target = ((ArrayAccessExpressionTree) parent).expression().symbolType();
    } else if (parent instanceof ExpressionTree) {
        target = ((ExpressionTree) parent).symbolType();
    }
    return target;
}
Also used : JavaType(org.sonar.java.resolve.JavaType) TypeVariableJavaType(org.sonar.java.resolve.TypeVariableJavaType) Type(org.sonar.plugins.java.api.semantic.Type) MethodJavaType(org.sonar.java.resolve.MethodJavaType) JavaSymbol(org.sonar.java.resolve.JavaSymbol) MethodJavaSymbol(org.sonar.java.resolve.JavaSymbol.MethodJavaSymbol) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) ArrayAccessExpressionTree(org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) MethodJavaSymbol(org.sonar.java.resolve.JavaSymbol.MethodJavaSymbol) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) Tree(org.sonar.plugins.java.api.tree.Tree) TypeCastTree(org.sonar.plugins.java.api.tree.TypeCastTree) ArrayAccessExpressionTree(org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) ArrayAccessExpressionTree(org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree) MethodJavaType(org.sonar.java.resolve.MethodJavaType) MethodJavaSymbol(org.sonar.java.resolve.JavaSymbol.MethodJavaSymbol) CheckForNull(javax.annotation.CheckForNull)

Example 5 with TypeCastTree

use of org.sonar.plugins.java.api.tree.TypeCastTree in project sonar-java by SonarSource.

the class RedundantTypeCastCheck method visitNode.

@Override
public void visitNode(Tree tree) {
    if (!hasSemantic()) {
        return;
    }
    TypeCastTree typeCastTree = (TypeCastTree) tree;
    Type cast = typeCastTree.type().symbolType();
    Type target = targetType(typeCastTree);
    Type expressionType = typeCastTree.expression().symbolType();
    if (isPrimitiveWrapperInConditional(expressionType, typeCastTree) || requiredForMemberAccess(typeCastTree)) {
        // Primitive wrappers excluded because covered by S2154
        return;
    }
    if (target != null && (isRedundantNumericalCast(cast, expressionType) || isUnnecessarySubtypeCast(expressionType, typeCastTree, target))) {
        reportIssue(typeCastTree.type(), "Remove this unnecessary cast to \"" + cast + "\".");
    }
}
Also used : TypeCastTree(org.sonar.plugins.java.api.tree.TypeCastTree) JavaType(org.sonar.java.resolve.JavaType) TypeVariableJavaType(org.sonar.java.resolve.TypeVariableJavaType) Type(org.sonar.plugins.java.api.semantic.Type) MethodJavaType(org.sonar.java.resolve.MethodJavaType)

Aggregations

TypeCastTree (org.sonar.plugins.java.api.tree.TypeCastTree)6 JavaType (org.sonar.java.resolve.JavaType)3 MethodJavaType (org.sonar.java.resolve.MethodJavaType)3 TypeVariableJavaType (org.sonar.java.resolve.TypeVariableJavaType)3 Type (org.sonar.plugins.java.api.semantic.Type)3 VariableTree (org.sonar.plugins.java.api.tree.VariableTree)3 Test (org.junit.Test)2 JavaSymbol (org.sonar.java.resolve.JavaSymbol)2 MethodJavaSymbol (org.sonar.java.resolve.JavaSymbol.MethodJavaSymbol)2 ArrayAccessExpressionTree (org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree)2 ExpressionTree (org.sonar.plugins.java.api.tree.ExpressionTree)2 MethodInvocationTree (org.sonar.plugins.java.api.tree.MethodInvocationTree)2 MethodTree (org.sonar.plugins.java.api.tree.MethodTree)2 Tree (org.sonar.plugins.java.api.tree.Tree)2 CheckForNull (javax.annotation.CheckForNull)1 Symbol (org.sonar.plugins.java.api.semantic.Symbol)1 AnnotationTree (org.sonar.plugins.java.api.tree.AnnotationTree)1 ArrayTypeTree (org.sonar.plugins.java.api.tree.ArrayTypeTree)1 ClassTree (org.sonar.plugins.java.api.tree.ClassTree)1 MemberSelectExpressionTree (org.sonar.plugins.java.api.tree.MemberSelectExpressionTree)1