Search in sources :

Example 76 with ClassTree

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

the class ValueBasedUtilsTest method testIsValueBased.

@Test
public void testIsValueBased() throws Exception {
    File file = new File("src/test/files/checks/helpers/ValueBasedUtilsTest.java");
    CompilationUnitTree tree = (CompilationUnitTree) JavaParser.createParser().parse(file);
    SemanticModel.createFor(tree, new SquidClassLoader(Collections.emptyList()));
    List<Tree> members = ((ClassTree) tree.types().get(0)).members();
    members.stream().forEach(member -> checkMember((VariableTree) member));
}
Also used : CompilationUnitTree(org.sonar.plugins.java.api.tree.CompilationUnitTree) ClassTree(org.sonar.plugins.java.api.tree.ClassTree) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) CompilationUnitTree(org.sonar.plugins.java.api.tree.CompilationUnitTree) Tree(org.sonar.plugins.java.api.tree.Tree) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) ClassTree(org.sonar.plugins.java.api.tree.ClassTree) File(java.io.File) SquidClassLoader(org.sonar.java.bytecode.loader.SquidClassLoader) Test(org.junit.Test)

Example 77 with ClassTree

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

the class TypeAndReferenceSolver method visitNewClass.

@Override
public void visitNewClass(NewClassTree tree) {
    NewClassTreeImpl newClassTreeImpl = (NewClassTreeImpl) tree;
    if (newClassTreeImpl.isTypeSet()) {
        return;
    }
    List<JavaType> typeArgumentsTypes = ImmutableList.of();
    if (tree.typeArguments() != null) {
        resolveAs((List<Tree>) tree.typeArguments(), JavaSymbol.TYP);
        typeArgumentsTypes = tree.typeArguments().stream().map(this::getType).collect(Collectors.toList());
    }
    resolveAs((List<ExpressionTree>) tree.arguments(), JavaSymbol.VAR);
    List<JavaType> parameterTypes = getParameterTypes(tree.arguments());
    Resolve.Env newClassEnv = semanticModel.getEnv(tree);
    ExpressionTree enclosingExpression = tree.enclosingExpression();
    TypeTree typeTree = tree.identifier();
    IdentifierTree constructorIdentifier = newClassTreeImpl.getConstructorIdentifier();
    JavaType identifierType = resolveIdentifierType(newClassEnv, enclosingExpression, typeTree, constructorIdentifier.name());
    JavaSymbol.TypeJavaSymbol constructorIdentifierSymbol = (JavaSymbol.TypeJavaSymbol) identifierType.symbol();
    constructorIdentifierSymbol.addUsage(constructorIdentifier);
    parameterTypes = addImplicitOuterClassParameter(parameterTypes, constructorIdentifierSymbol);
    Resolution resolution = resolveConstructorSymbol(constructorIdentifier, identifierType, newClassEnv, parameterTypes, typeArgumentsTypes);
    JavaType constructedType = identifierType;
    if (resolution.symbol().isMethodSymbol()) {
        constructedType = ((MethodJavaType) resolution.type()).resultType;
        if (constructedType.isTagged(JavaType.DEFERRED)) {
            Tree parent = newClassTreeImpl.parent();
            if (parent.is(Tree.Kind.MEMBER_SELECT)) {
                constructedType = resolve.parametrizedTypeWithErasure((ParametrizedTypeJavaType) identifierType);
            } else {
                // will be resolved by type inference
                ((DeferredType) constructedType).setTree(newClassTreeImpl);
            }
        } else if (identifierType.symbol().isInterface()) {
            // constructor of interface always resolve to 'Object' no-arg constructor
            registerType(typeTree, identifierType);
        } else {
            registerType(typeTree, resolution.type());
        }
    }
    ClassTree classBody = tree.classBody();
    if (classBody != null) {
        constructedType = getAnonymousClassType(identifierType, constructedType, classBody);
    }
    registerType(tree, constructedType);
}
Also used : NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree) ClassTree(org.sonar.plugins.java.api.tree.ClassTree) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) 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) NewClassTreeImpl(org.sonar.java.model.expression.NewClassTreeImpl) AbstractTypedTree(org.sonar.java.model.AbstractTypedTree) UnionTypeTree(org.sonar.plugins.java.api.tree.UnionTypeTree) MemberSelectExpressionTree(org.sonar.plugins.java.api.tree.MemberSelectExpressionTree) ArrayTypeTree(org.sonar.plugins.java.api.tree.ArrayTypeTree) TypeTree(org.sonar.plugins.java.api.tree.TypeTree) NewArrayTree(org.sonar.plugins.java.api.tree.NewArrayTree) ContinueStatementTree(org.sonar.plugins.java.api.tree.ContinueStatementTree) ExpressionStatementTree(org.sonar.plugins.java.api.tree.ExpressionStatementTree) ParameterizedTypeTree(org.sonar.plugins.java.api.tree.ParameterizedTypeTree) TypeCastTree(org.sonar.plugins.java.api.tree.TypeCastTree) NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree) AssignmentExpressionTree(org.sonar.plugins.java.api.tree.AssignmentExpressionTree) ClassTree(org.sonar.plugins.java.api.tree.ClassTree) UnaryExpressionTree(org.sonar.plugins.java.api.tree.UnaryExpressionTree) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) WildcardTree(org.sonar.plugins.java.api.tree.WildcardTree) LabeledStatementTree(org.sonar.plugins.java.api.tree.LabeledStatementTree) BreakStatementTree(org.sonar.plugins.java.api.tree.BreakStatementTree) ThrowStatementTree(org.sonar.plugins.java.api.tree.ThrowStatementTree) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) ParenthesizedTree(org.sonar.plugins.java.api.tree.ParenthesizedTree) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) ArrayDimensionTree(org.sonar.plugins.java.api.tree.ArrayDimensionTree) EnumConstantTree(org.sonar.plugins.java.api.tree.EnumConstantTree) MethodReferenceTree(org.sonar.plugins.java.api.tree.MethodReferenceTree) AnnotationTree(org.sonar.plugins.java.api.tree.AnnotationTree) BinaryExpressionTree(org.sonar.plugins.java.api.tree.BinaryExpressionTree) ReturnStatementTree(org.sonar.plugins.java.api.tree.ReturnStatementTree) LiteralTree(org.sonar.plugins.java.api.tree.LiteralTree) ConditionalExpressionTree(org.sonar.plugins.java.api.tree.ConditionalExpressionTree) ImportTree(org.sonar.plugins.java.api.tree.ImportTree) PrimitiveTypeTree(org.sonar.plugins.java.api.tree.PrimitiveTypeTree) TypeParameterTree(org.sonar.plugins.java.api.tree.TypeParameterTree) Tree(org.sonar.plugins.java.api.tree.Tree) ArrayAccessExpressionTree(org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) LambdaExpressionTree(org.sonar.plugins.java.api.tree.LambdaExpressionTree) InstanceOfTree(org.sonar.plugins.java.api.tree.InstanceOfTree) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) MemberSelectExpressionTree(org.sonar.plugins.java.api.tree.MemberSelectExpressionTree) AssignmentExpressionTree(org.sonar.plugins.java.api.tree.AssignmentExpressionTree) UnaryExpressionTree(org.sonar.plugins.java.api.tree.UnaryExpressionTree) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) BinaryExpressionTree(org.sonar.plugins.java.api.tree.BinaryExpressionTree) ConditionalExpressionTree(org.sonar.plugins.java.api.tree.ConditionalExpressionTree) ArrayAccessExpressionTree(org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree) LambdaExpressionTree(org.sonar.plugins.java.api.tree.LambdaExpressionTree) Resolution(org.sonar.java.resolve.Resolve.Resolution)

Example 78 with ClassTree

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

the class TypeAndReferenceSolver method visitEnumConstant.

@Override
public void visitEnumConstant(EnumConstantTree tree) {
    scan(tree.modifiers());
    NewClassTree newClassTree = tree.initializer();
    scan(newClassTree.enclosingExpression());
    // register identifier type
    registerType(newClassTree.identifier(), ((VariableTreeImpl) tree).getSymbol().getType());
    scan(newClassTree.typeArguments());
    scan(newClassTree.arguments());
    ClassTree classBody = newClassTree.classBody();
    if (classBody != null) {
        scan(classBody);
        ((ClassJavaType) classBody.symbol().type()).supertype = getType(newClassTree.identifier());
    }
    resolveConstructorSymbol(tree.simpleName(), newClassTree.identifier().symbolType(), semanticModel.getEnv(tree), getParameterTypes(newClassTree.arguments()));
}
Also used : NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree) ClassTree(org.sonar.plugins.java.api.tree.ClassTree) NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree) VariableTreeImpl(org.sonar.java.model.declaration.VariableTreeImpl)

Example 79 with ClassTree

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

the class SecondPass method complete.

private void complete(JavaSymbol.TypeJavaSymbol symbol) {
    Resolve.Env env = semanticModel.getEnv(symbol);
    ClassJavaType type = (ClassJavaType) symbol.type;
    if (!symbol.isFlag(Flags.ANNOTATION)) {
        // JLS8 15.8.3 If this is a class or interface (default methods), enter symbol for "this"
        symbol.members.enter(new JavaSymbol.VariableJavaSymbol(Flags.FINAL, "this", symbol.type, symbol));
    }
    if ("".equals(symbol.name)) {
        // Anonymous Class Declaration
        // FIXME(Godin): This case avoids NPE which occurs because semanticModel has no associations for anonymous classes.
        type.interfaces = ImmutableList.of();
        return;
    }
    ClassTree tree = symbol.declaration;
    completeTypeParameters(tree.typeParameters(), env);
    // Interfaces
    ImmutableList.Builder<JavaType> interfaces = ImmutableList.builder();
    tree.superInterfaces().stream().map(interfaceTree -> resolveType(env, interfaceTree)).filter(Objects::nonNull).forEach(interfaces::add);
    if (tree.is(Tree.Kind.ANNOTATION_TYPE)) {
        // JLS8 9.6: The direct superinterface of every annotation type is java.lang.annotation.Annotation.
        // (Godin): Note that "extends" and "implements" clauses are forbidden by grammar for annotation types
        interfaces.add(symbols.annotationType);
    }
    if (tree.is(Tree.Kind.ENUM, Tree.Kind.INTERFACE) && symbol.owner.isKind(JavaSymbol.TYP)) {
        // JSL8 8.9: A nested enum type is implicitly static. It is permitted for the declaration of a nested
        // enum type to redundantly specify the static modifier.
        symbol.flags |= Flags.STATIC;
    }
    type.interfaces = interfaces.build();
    populateSuperclass(symbol, env, type);
    if ((symbol.flags() & Flags.INTERFACE) == 0) {
        symbol.members.enter(new JavaSymbol.VariableJavaSymbol(Flags.FINAL, "super", type.supertype, symbol));
    }
    // Register default constructor
    if (tree.is(Tree.Kind.CLASS, Tree.Kind.ENUM) && symbol.lookupSymbols(CONSTRUCTOR_NAME).isEmpty()) {
        List<JavaType> argTypes = ImmutableList.of();
        if (!symbol.isStatic()) {
            // JLS8 - 8.8.1 & 8.8.9 : constructors of inner class have an implicit first arg of its directly enclosing class type
            JavaSymbol owner = symbol.owner();
            if (!owner.isPackageSymbol()) {
                argTypes = ImmutableList.of(owner.enclosingClass().type);
            }
        }
        JavaSymbol.MethodJavaSymbol defaultConstructor = new JavaSymbol.MethodJavaSymbol(symbol.flags & Flags.ACCESS_FLAGS, CONSTRUCTOR_NAME, symbol);
        MethodJavaType defaultConstructorType = new MethodJavaType(argTypes, null, ImmutableList.of(), symbol);
        defaultConstructor.setMethodType(defaultConstructorType);
        defaultConstructor.parameters = new Scope(defaultConstructor);
        symbol.members.enter(defaultConstructor);
    }
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) ClassTree(org.sonar.plugins.java.api.tree.ClassTree)

Example 80 with ClassTree

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

the class SecondPass method populateSuperclass.

private void populateSuperclass(JavaSymbol.TypeJavaSymbol symbol, Resolve.Env env, ClassJavaType type) {
    ClassTree tree = symbol.declaration;
    Tree superClassTree = tree.superClass();
    if (superClassTree != null) {
        type.supertype = resolveType(env, superClassTree);
        checkHierarchyCycles(symbol.type);
    } else if (tree.is(Tree.Kind.ENUM)) {
        // JLS8 8.9: The direct superclass of an enum type E is Enum<E>.
        Scope enumParameters = ((JavaSymbol.TypeJavaSymbol) symbols.enumType.symbol()).typeParameters();
        TypeVariableJavaType enumParameter = (TypeVariableJavaType) enumParameters.lookup("E").get(0).type();
        type.supertype = parametrizedTypeCache.getParametrizedTypeType(symbols.enumType.symbol, new TypeSubstitution().add(enumParameter, type));
    } else if (tree.is(Tree.Kind.CLASS, Tree.Kind.INTERFACE)) {
        // For CLASS JLS8 8.1.4: the direct superclass of the class type C<F1,...,Fn> is
        // the type given in the extends clause of the declaration of C
        // if an extends clause is present, or Object otherwise.
        // For INTERFACE JLS8 9.1.3: While every class is an extension of class Object, there is no single interface of which all interfaces are
        // extensions.
        // but we can call object method on any interface type.
        type.supertype = symbols.objectType;
    }
}
Also used : ClassTree(org.sonar.plugins.java.api.tree.ClassTree) TypeTree(org.sonar.plugins.java.api.tree.TypeTree) AbstractTypedTree(org.sonar.java.model.AbstractTypedTree) TypeParameterTree(org.sonar.plugins.java.api.tree.TypeParameterTree) Tree(org.sonar.plugins.java.api.tree.Tree) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) ClassTree(org.sonar.plugins.java.api.tree.ClassTree) MethodTree(org.sonar.plugins.java.api.tree.MethodTree)

Aggregations

ClassTree (org.sonar.plugins.java.api.tree.ClassTree)116 Tree (org.sonar.plugins.java.api.tree.Tree)53 MethodTree (org.sonar.plugins.java.api.tree.MethodTree)47 CompilationUnitTree (org.sonar.plugins.java.api.tree.CompilationUnitTree)45 Test (org.junit.Test)41 VariableTree (org.sonar.plugins.java.api.tree.VariableTree)37 IdentifierTree (org.sonar.plugins.java.api.tree.IdentifierTree)32 Symbol (org.sonar.plugins.java.api.semantic.Symbol)31 NewClassTree (org.sonar.plugins.java.api.tree.NewClassTree)23 List (java.util.List)19 Type (org.sonar.plugins.java.api.semantic.Type)18 File (java.io.File)14 MethodInvocationTree (org.sonar.plugins.java.api.tree.MethodInvocationTree)13 Rule (org.sonar.check.Rule)12 ExpressionTree (org.sonar.plugins.java.api.tree.ExpressionTree)12 Collectors (java.util.stream.Collectors)10 SquidClassLoader (org.sonar.java.bytecode.loader.SquidClassLoader)10 IssuableSubscriptionVisitor (org.sonar.plugins.java.api.IssuableSubscriptionVisitor)10 ImmutableList (com.google.common.collect.ImmutableList)9 MemberSelectExpressionTree (org.sonar.plugins.java.api.tree.MemberSelectExpressionTree)9