use of org.sonar.plugins.java.api.tree.MemberSelectExpressionTree in project sonar-java by SonarSource.
the class TypeAndReferenceSolver method resolveMethodSymbol.
@CheckForNull
private Resolve.Resolution resolveMethodSymbol(Tree methodSelect, Resolve.Env methodEnv, List<JavaType> argTypes, List<JavaType> typeParamTypes) {
Resolve.Resolution resolution;
IdentifierTree identifier;
if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
MemberSelectExpressionTree mset = (MemberSelectExpressionTree) methodSelect;
resolveAs(mset.expression(), JavaSymbol.TYP | JavaSymbol.VAR);
JavaType type = getType(mset.expression());
if (type.isTagged(JavaType.DEFERRED)) {
return null;
}
identifier = mset.identifier();
resolution = resolve.findMethod(methodEnv, type, identifier.name(), argTypes, typeParamTypes);
} else if (methodSelect.is(Tree.Kind.IDENTIFIER)) {
identifier = (IdentifierTree) methodSelect;
resolution = resolve.findMethod(methodEnv, identifier.name(), argTypes, typeParamTypes);
} else {
throw new IllegalStateException("Method select in method invocation is not of the expected type " + methodSelect);
}
registerType(identifier, resolution.type());
associateReference(identifier, resolution.symbol());
return resolution;
}
use of org.sonar.plugins.java.api.tree.MemberSelectExpressionTree in project sonar-java by SonarSource.
the class TypeAndReferenceSolver method inferReturnTypeFromInferedArgs.
private void inferReturnTypeFromInferedArgs(MethodInvocationTree tree, Resolve.Env methodEnv, List<JavaType> argTypes, List<JavaType> typeParamTypes, JavaType returnType, TypeSubstitution typeSubstitution) {
List<JavaType> parameterTypes = getParameterTypes(tree.arguments());
if (!parameterTypes.equals(argTypes)) {
IdentifierTree identifier = null;
Resolution resolution = null;
Tree methodSelect = tree.methodSelect();
if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
MemberSelectExpressionTree mset = (MemberSelectExpressionTree) methodSelect;
JavaType type = getType(mset.expression());
if (type.isTagged(JavaType.DEFERRED)) {
throw new IllegalStateException("type of arg should not be defered anymore ??");
}
identifier = mset.identifier();
resolution = resolve.findMethod(methodEnv, type, identifier.name(), parameterTypes, typeParamTypes);
} else if (methodSelect.is(Tree.Kind.IDENTIFIER)) {
identifier = (IdentifierTree) methodSelect;
resolution = resolve.findMethod(methodEnv, identifier.name(), parameterTypes, typeParamTypes);
}
if (resolution != null && returnType != resolution.type() && resolution.symbol().isMethodSymbol()) {
MethodJavaType methodType = (MethodJavaType) resolution.type();
if (!methodType.resultType.isTagged(JavaType.DEFERRED)) {
registerType(tree, resolve.applySubstitution(methodType.resultType, typeSubstitution));
// update type associated to identifier as it may have been inferred deeper when re-resolving method with new parameter types
registerType(identifier, methodType);
}
}
} else {
registerType(tree, resolve.applySubstitution(returnType, typeSubstitution));
}
}
use of org.sonar.plugins.java.api.tree.MemberSelectExpressionTree in project sonar-java by SonarSource.
the class ExceptionalYieldChecker method reportIssue.
private void reportIssue(ExplodedGraph.Node node, ExceptionalCheckBasedYield yield, SECheck check) {
MethodInvocationTree mit = (MethodInvocationTree) node.programPoint.syntaxTree();
ExpressionTree methodSelect = mit.methodSelect();
String methodName = mit.symbol().name();
Tree reportTree = methodSelect;
if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
reportTree = ((MemberSelectExpressionTree) methodSelect).identifier();
}
JavaFileScannerContext.Location methodInvocationMessage;
int parameterCausingExceptionIndex = yield.parameterCausingExceptionIndex();
IdentifierTree identifierTree = FlowComputation.getArgumentIdentifier(mit, parameterCausingExceptionIndex);
if (identifierTree != null) {
methodInvocationMessage = new JavaFileScannerContext.Location(String.format("'%s' is passed to '%s()'.", identifierTree.name(), methodName), identifierTree);
} else {
methodInvocationMessage = new JavaFileScannerContext.Location(String.format("'%s()' is invoked.", methodName), reportTree);
}
Flow argumentChangingNameFlows = flowsForArgumentsChangingName(yield, mit);
Set<Flow> argumentsFlows = flowsForMethodArguments(node, mit, parameterCausingExceptionIndex);
Set<Flow> exceptionFlows = yield.exceptionFlows();
ImmutableSet.Builder<Flow> flows = ImmutableSet.builder();
for (Flow argumentFlow : argumentsFlows) {
for (Flow exceptionFlow : exceptionFlows) {
flows.add(Flow.builder().addAll(exceptionFlow).addAll(argumentChangingNameFlows).add(methodInvocationMessage).addAll(argumentFlow).build());
}
}
check.reportIssue(reportTree, String.format(message, methodName), flows.build());
}
use of org.sonar.plugins.java.api.tree.MemberSelectExpressionTree in project sonar-java by SonarSource.
the class NullDereferenceCheck method reportIssue.
private void reportIssue(SymbolicValue currentVal, Tree syntaxNode, ExplodedGraph.Node node) {
String message = "A \"NullPointerException\" could be thrown; ";
if (syntaxNode.is(Tree.Kind.MEMBER_SELECT) && ((MemberSelectExpressionTree) syntaxNode).expression().is(Tree.Kind.METHOD_INVOCATION)) {
message += "\"" + SyntaxTreeNameFinder.getName(syntaxNode) + "()\" can return null.";
} else {
message += "\"" + SyntaxTreeNameFinder.getName(syntaxNode) + "\" is nullable here.";
}
SymbolicValue val = null;
if (!SymbolicValue.NULL_LITERAL.equals(currentVal)) {
val = currentVal;
}
Symbol dereferencedSymbol = dereferencedSymbol(syntaxNode);
Set<Flow> flows = FlowComputation.flow(node, val, Lists.newArrayList(ObjectConstraint.class), dereferencedSymbol).stream().filter(f -> !f.isEmpty()).map(f -> addDereferenceMessage(f, syntaxNode)).collect(Collectors.toSet());
reportIssue(syntaxNode, message, flows);
}
use of org.sonar.plugins.java.api.tree.MemberSelectExpressionTree in project sonar-java by SonarSource.
the class NullDereferenceCheck method checkPreStatement.
@Override
public ProgramState checkPreStatement(CheckerContext context, Tree syntaxNode) {
if (context.getState().peekValue() == null) {
// stack is empty, nothing to do.
return context.getState();
}
if (syntaxNode.is(Tree.Kind.METHOD_INVOCATION)) {
MethodInvocationTree methodInvocation = (MethodInvocationTree) syntaxNode;
Tree methodSelect = methodInvocation.methodSelect();
if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
SymbolicValue dereferencedSV = context.getState().peekValue(methodInvocation.arguments().size());
return checkConstraint(context, methodSelect, dereferencedSV);
}
}
if (syntaxNode.is(Tree.Kind.ARRAY_ACCESS_EXPRESSION)) {
Tree toCheck = ((ArrayAccessExpressionTree) syntaxNode).expression();
SymbolicValue currentVal = context.getState().peekValue(1);
return checkConstraint(context, toCheck, currentVal);
}
if (syntaxNode.is(Tree.Kind.MEMBER_SELECT)) {
return checkMemberSelect(context, (MemberSelectExpressionTree) syntaxNode, context.getState().peekValue());
}
return context.getState();
}
Aggregations