|
22 | 22 | import org.apache.commons.lang3.NotImplementedException; |
23 | 23 | import spoon.reflect.code.BinaryOperatorKind; |
24 | 24 | import spoon.reflect.code.CtAssignment; |
| 25 | +import spoon.reflect.code.CtConditional; |
25 | 26 | import spoon.reflect.code.CtBinaryOperator; |
26 | 27 | import spoon.reflect.code.CtExpression; |
27 | 28 | import spoon.reflect.code.CtFieldRead; |
@@ -317,19 +318,62 @@ private Predicate getOperatorAssignmentRefinement(CtExpression<?> element) throw |
317 | 318 | Predicate left = getOperatorAssignmentRefinement(binaryOperator.getLeftHandOperand()); |
318 | 319 | Predicate right = getOperatorAssignmentRefinement(binaryOperator.getRightHandOperand()); |
319 | 320 | return Predicate.createOperation(left, getOperatorFromKind(binaryOperator.getKind()), right); |
| 321 | + } else if (element instanceof CtConditional<?> conditional) { |
| 322 | + Predicate condition = getConditionRefinement(conditional.getCondition()); |
| 323 | + Predicate thenExpression = getOperatorAssignmentRefinement(conditional.getThenExpression()); |
| 324 | + Predicate elseExpression = getOperatorAssignmentRefinement(conditional.getElseExpression()); |
| 325 | + return Predicate.createITE(condition, thenExpression, elseExpression); |
320 | 326 | } else if (element instanceof CtLiteral<?> literal) { |
321 | 327 | if (literal.getValue() == null) |
322 | 328 | throw new CustomError("Null literals are not supported", literal.getPosition()); |
323 | 329 | return new Predicate(literal.getValue().toString(), element); |
| 330 | + } else if (element instanceof CtInvocation<?>) { |
| 331 | + VariableInstance invocationValue = (VariableInstance) element.getMetadata(Keys.TARGET); |
| 332 | + if (invocationValue != null) |
| 333 | + return Predicate.createVar(invocationValue.getName()); |
324 | 334 | } |
325 | | - // unwrap wildcard equality: _ == expr -> expr |
326 | | - Predicate refinement = rtc.getRefinement(element); |
| 335 | + return valueFromRefinement(element, rtc.getRefinement(element)); |
| 336 | + } |
| 337 | + |
| 338 | + private Predicate getConditionRefinement(CtExpression<Boolean> condition) throws LJError { |
| 339 | + Predicate refinement = rtc.getRefinement(condition); |
| 340 | + Optional<Predicate> value = unwrapWildcardEquality(refinement); |
| 341 | + if (value.isPresent()) |
| 342 | + return value.get(); |
| 343 | + return refinement; |
| 344 | + } |
| 345 | + |
| 346 | + private Optional<Predicate> unwrapWildcardEquality(Predicate refinement) { |
327 | 347 | Expression expression = unwrapGroupExpression(refinement.getExpression()); |
328 | 348 | if (expression instanceof BinaryExpression binaryExpression && Ops.EQ.equals(binaryExpression.getOperator()) |
329 | 349 | && Keys.WILDCARD.equals(binaryExpression.getFirstOperand().toString())) { |
330 | | - return new Predicate(binaryExpression.getSecondOperand()); |
| 350 | + return Optional.of(new Predicate(binaryExpression.getSecondOperand())); |
331 | 351 | } |
332 | | - return refinement; |
| 352 | + return Optional.empty(); |
| 353 | + } |
| 354 | + |
| 355 | + private Predicate valueFromRefinement(CtExpression<?> element, Predicate refinement) { |
| 356 | + if (refinement == null) |
| 357 | + return createFreshValue(element, new Predicate()); |
| 358 | + |
| 359 | + Optional<Predicate> value = unwrapWildcardEquality(refinement); |
| 360 | + if (value.isPresent()) |
| 361 | + return value.get(); |
| 362 | + |
| 363 | + Expression expression = unwrapGroupExpression(refinement.getExpression()); |
| 364 | + boolean hasWildcard = refinement.getVariableNames().contains(Keys.WILDCARD); |
| 365 | + if (!hasWildcard && !expression.isBooleanExpression()) |
| 366 | + return new Predicate(expression); |
| 367 | + |
| 368 | + Predicate constraint = hasWildcard ? refinement : new Predicate(); |
| 369 | + return createFreshValue(element, constraint); |
| 370 | + } |
| 371 | + |
| 372 | + private Predicate createFreshValue(CtExpression<?> element, Predicate refinement) { |
| 373 | + String newName = String.format(Formats.FRESH, rtc.getContext().getCounter()); |
| 374 | + Predicate freshRefinement = refinement.substituteVariable(Keys.WILDCARD, newName); |
| 375 | + rtc.getContext().addVarToContext(newName, element.getType(), freshRefinement, element); |
| 376 | + return Predicate.createVar(newName); |
333 | 377 | } |
334 | 378 |
|
335 | 379 | private Expression unwrapGroupExpression(Expression expression) { |
|
0 commit comments