mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-163213 Method contract is not inferred when it returns the result of string concatenation
This commit is contained in:
+21
-11
@@ -117,17 +117,7 @@ class ContractInferenceInterpreter {
|
||||
|
||||
IElementType type = expr.getTokenType();
|
||||
if (type == POLYADIC_EXPRESSION || type == BINARY_EXPRESSION) {
|
||||
List<LighterASTNode> operands = getExpressionChildren(myTree, expr);
|
||||
if (operands.size() == 2) {
|
||||
boolean equality = firstChildOfType(myTree, expr, JavaTokenType.EQEQ) != null;
|
||||
if (equality || firstChildOfType(myTree, expr, JavaTokenType.NE) != null) {
|
||||
return asPreContracts(visitEqualityComparison(states, operands.get(0), operands.get(1), equality));
|
||||
}
|
||||
}
|
||||
boolean logicalAnd = firstChildOfType(myTree, expr, JavaTokenType.ANDAND) != null;
|
||||
if (logicalAnd || firstChildOfType(myTree, expr, JavaTokenType.OROR) != null) {
|
||||
return asPreContracts(visitLogicalOperation(operands, logicalAnd, states));
|
||||
}
|
||||
return visitPolyadic(states, expr);
|
||||
}
|
||||
|
||||
if (type == CONDITIONAL_EXPRESSION) {
|
||||
@@ -190,6 +180,26 @@ class ContractInferenceInterpreter {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<PreContract> visitPolyadic(List<ValueConstraint[]> states, @NotNull LighterASTNode expr) {
|
||||
if (firstChildOfType(myTree, expr, JavaTokenType.PLUS) != null) {
|
||||
return asPreContracts(ContainerUtil.map(states, s -> new MethodContract(s, NOT_NULL_VALUE)));
|
||||
}
|
||||
|
||||
List<LighterASTNode> operands = getExpressionChildren(myTree, expr);
|
||||
if (operands.size() == 2) {
|
||||
boolean equality = firstChildOfType(myTree, expr, JavaTokenType.EQEQ) != null;
|
||||
if (equality || firstChildOfType(myTree, expr, JavaTokenType.NE) != null) {
|
||||
return asPreContracts(visitEqualityComparison(states, operands.get(0), operands.get(1), equality));
|
||||
}
|
||||
}
|
||||
boolean logicalAnd = firstChildOfType(myTree, expr, JavaTokenType.ANDAND) != null;
|
||||
if (logicalAnd || firstChildOfType(myTree, expr, JavaTokenType.OROR) != null) {
|
||||
return asPreContracts(visitLogicalOperation(operands, logicalAnd, states));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<PreContract> asPreContracts(List<MethodContract> contracts) {
|
||||
return ContainerUtil.map(contracts, KnownContract::new);
|
||||
|
||||
+18
@@ -438,6 +438,24 @@ class ContractInferenceFromSourceTest extends LightCodeInsightFixtureTestCase {
|
||||
assert c == ['null -> null']
|
||||
}
|
||||
|
||||
void "test string concatenation"() {
|
||||
def c = inferContracts("""
|
||||
public static String test(String s1, String s2) {
|
||||
return s1 != null ? s1.trim()+s2.trim() : unknown();
|
||||
}
|
||||
""")
|
||||
assert c == ['!null, _ -> !null']
|
||||
}
|
||||
|
||||
void "test int addition"() {
|
||||
def c = inferContracts("""
|
||||
public static int test(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
""")
|
||||
assert c == []
|
||||
}
|
||||
|
||||
void "test compare with string literal"() {
|
||||
def c = inferContracts("""
|
||||
String s(String s) {
|
||||
|
||||
+4
@@ -73,6 +73,10 @@ String bar() { return "z"; }
|
||||
assert inferNullity(parse('String bar() { return equals(2) ? "a" : equals(3) ? null : "a"; }; ')) == NULLABLE
|
||||
}
|
||||
|
||||
void "test string concatenation"() {
|
||||
assert inferNullity(parse('String bar(String s1, String s2) { return s1 + s2; }; ')) == NOT_NULL
|
||||
}
|
||||
|
||||
void "test delegation to nullable means nothing"() {
|
||||
assert inferNullity(parse('String foo() { return bar("2"); }; String bar(String s) { if (s != "2") return null; return "a"; }; ')) == UNKNOWN
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user