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));
}
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);
}
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()));
}
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);
}
}
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;
}
}
Aggregations