private static boolean isNonNullMethodInvocation(ExpressionTree expr) { return expr.is(Tree.Kind.METHOD_INVOCATION) && isAnnotatedNonNull(((MethodInvocationTree) expr).symbol()); }
private static boolean isNonNullMethodInvocation(ExpressionTree expr) { return expr.is(Tree.Kind.METHOD_INVOCATION) && isAnnotatedNonNull(((MethodInvocationTree) expr).symbol()); }
private static boolean parameterCanBeNull(Symbol variableSymbol, boolean nullableParameters) { if (variableSymbol.type().isPrimitive()) { return false; } return isAnnotatedNullable(variableSymbol) || (nullableParameters && !isAnnotatedNonNull(variableSymbol)); }
private static boolean parameterCanBeNull(Symbol variableSymbol, boolean nullableParameters) { if (variableSymbol.type().isPrimitive()) { return false; } return isAnnotatedNullable(variableSymbol) || (nullableParameters && !isAnnotatedNonNull(variableSymbol)); }
@Override public void visitNode(Tree tree) { if (!hasSemantic()) { return; } MethodTree methodTree = (MethodTree) tree; List<VariableTree> params = methodTree.parameters(); if ("equals".equals(methodTree.symbol().name()) && params.size() == 1) { VariableTree variable = params.get(0); if (variable.type().symbolType().is("java.lang.Object") && NullableAnnotationUtils.isAnnotatedNonNull(variable.symbol())) { reportIssue(variable, "\"equals\" method parameters should not be marked \"@Nonnull\"."); } } }
private Iterable<ProgramState> startingStates(MethodTree tree, ProgramState currentState) { Stream<ProgramState> stateStream = Stream.of(currentState); boolean isEqualsMethod = EQUALS.matches(tree); boolean nonNullParameters = isGloballyAnnotatedParameterNonNull(methodTree.symbol()); boolean nullableParameters = isGloballyAnnotatedParameterNullable(methodTree.symbol()); boolean hasMethodBehavior = methodBehavior != null; for (final VariableTree variableTree : tree.parameters()) { // create final SymbolicValue sv = constraintManager.createSymbolicValue(variableTree); Symbol variableSymbol = variableTree.symbol(); if (hasMethodBehavior) { methodBehavior.addParameter(sv); } stateStream = stateStream.map(ps -> ps.put(variableSymbol, sv)); if (isEqualsMethod || parameterCanBeNull(variableSymbol, nullableParameters)) { stateStream = stateStream.flatMap((ProgramState ps) -> Stream.concat( sv.setConstraint(ps, ObjectConstraint.NULL).stream(), sv.setConstraint(ps, ObjectConstraint.NOT_NULL).stream() )); } else if (nonNullParameters || isAnnotatedNonNull(variableSymbol)) { stateStream = stateStream.flatMap(ps -> sv.setConstraint(ps, ObjectConstraint.NOT_NULL).stream()); } } return stateStream.collect(Collectors.toList()); }
@Override public void visitNode(Tree tree) { if (!hasSemantic()) { return; } MethodTree methodTree = (MethodTree) tree; List<VariableTree> params = methodTree.parameters(); if ("equals".equals(methodTree.symbol().name()) && params.size() == 1) { VariableTree variable = params.get(0); if (variable.type().symbolType().is("java.lang.Object") && NullableAnnotationUtils.isAnnotatedNonNull(variable.symbol())) { reportIssue(variable, "\"equals\" method parameters should not be marked \"@Nonnull\"."); } } }
private Iterable<ProgramState> startingStates(MethodTree tree, ProgramState currentState) { Stream<ProgramState> stateStream = Stream.of(currentState); boolean isEqualsMethod = EQUALS.matches(tree); boolean nonNullParameters = isGloballyAnnotatedParameterNonNull(methodTree.symbol()); boolean nullableParameters = isGloballyAnnotatedParameterNullable(methodTree.symbol()); boolean hasMethodBehavior = methodBehavior != null; for (final VariableTree variableTree : tree.parameters()) { // create final SymbolicValue sv = constraintManager.createSymbolicValue(variableTree); Symbol variableSymbol = variableTree.symbol(); if (hasMethodBehavior) { methodBehavior.addParameter(sv); } stateStream = stateStream.map(ps -> ps.put(variableSymbol, sv)); if (isEqualsMethod || parameterCanBeNull(variableSymbol, nullableParameters)) { stateStream = stateStream.flatMap((ProgramState ps) -> Stream.concat( sv.setConstraint(ps, ObjectConstraint.NULL).stream(), sv.setConstraint(ps, ObjectConstraint.NOT_NULL).stream() )); } else if (nonNullParameters || isAnnotatedNonNull(variableSymbol)) { stateStream = stateStream.flatMap(ps -> sv.setConstraint(ps, ObjectConstraint.NOT_NULL).stream()); } } return stateStream.collect(Collectors.toList()); }
private ProgramState handleSpecialMethods(ProgramState ps, MethodInvocationTree mit) { if (isAnnotatedNonNull(mit.symbol())) { return ps.addConstraint(ps.peekValue(), ObjectConstraint.NOT_NULL); } else if (OBJECT_WAIT_MATCHER.matches(mit)) { return ps.resetFieldValues(constraintManager, false); } return ps; }
private ProgramState handleSpecialMethods(ProgramState ps, MethodInvocationTree mit) { if (isAnnotatedNonNull(mit.symbol())) { return ps.addConstraint(ps.peekValue(), ObjectConstraint.NOT_NULL); } else if (OBJECT_WAIT_MATCHER.matches(mit)) { return ps.resetFieldValues(constraintManager, false); } return ps; }
/** * @see JLS8 4.12.5 for details */ private void executeVariable(VariableTree variableTree, @Nullable Tree terminator) { Symbol variableSymbol = variableTree.symbol(); if (variableTree.initializer() == null) { SymbolicValue sv = null; if (terminator != null && terminator.is(Tree.Kind.FOR_EACH_STATEMENT)) { sv = constraintManager.createSymbolicValue(variableTree); if (isAnnotatedNonNull(variableSymbol)) { programState = programState.addConstraint(sv, ObjectConstraint.NOT_NULL); } } else if (variableTree.parent().is(Tree.Kind.CATCH)) { sv = handleCatchVariable(variableSymbol.type()); // an exception have been thrown and caught, stack must be cleared // see notes in JVMS 8 - §6.5. - instruction "athrow" programState = programState.clearStack(); // exception variable is not null by definition programState = programState.addConstraint(sv, ObjectConstraint.NOT_NULL); } if (sv != null) { programState = programState.put(variableSymbol, sv); } } else { ProgramState.Pop unstack = programState.unstackValue(1); programState = unstack.state; programState = programState.put(variableSymbol, unstack.values.get(0)); } }
/** * @see JLS8 4.12.5 for details */ private void executeVariable(VariableTree variableTree, @Nullable Tree terminator) { Symbol variableSymbol = variableTree.symbol(); if (variableTree.initializer() == null) { SymbolicValue sv = null; if (terminator != null && terminator.is(Tree.Kind.FOR_EACH_STATEMENT)) { sv = constraintManager.createSymbolicValue(variableTree); if (isAnnotatedNonNull(variableSymbol)) { programState = programState.addConstraint(sv, ObjectConstraint.NOT_NULL); } } else if (variableTree.parent().is(Tree.Kind.CATCH)) { sv = handleCatchVariable(variableSymbol.type()); // an exception have been thrown and caught, stack must be cleared // see notes in JVMS 8 - §6.5. - instruction "athrow" programState = programState.clearStack(); // exception variable is not null by definition programState = programState.addConstraint(sv, ObjectConstraint.NOT_NULL); } if (sv != null) { programState = programState.put(variableSymbol, sv); } } else { ProgramState.Pop unstack = programState.unstackValue(1); programState = unstack.state; programState = programState.put(variableSymbol, unstack.values.get(0)); } }