From 54630aeea9c2d9c22435f68c5889976b34112616 Mon Sep 17 00:00:00 2001 From: Mr-Pine Date: Sun, 7 Apr 2024 21:08:11 +0200 Subject: [PATCH] Fix tests and complete exhaustiveness for java 21+ --- .../inria/controlflow/ControlFlowBuilder.java | 13 ++++++----- .../ForwardFlowBuilderVisitorTest.java | 22 +++++++++--------- .../control-flow/ControlFlowArithmetic.java | 23 ++++++++++--------- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/spoon-control-flow/src/main/java/fr/inria/controlflow/ControlFlowBuilder.java b/spoon-control-flow/src/main/java/fr/inria/controlflow/ControlFlowBuilder.java index f4d7ddc4d4b..a2a9a3afb11 100644 --- a/spoon-control-flow/src/main/java/fr/inria/controlflow/ControlFlowBuilder.java +++ b/spoon-control-flow/src/main/java/fr/inria/controlflow/ControlFlowBuilder.java @@ -851,19 +851,20 @@ private boolean checkExhaustive(CtAbstractSwitch switchElement) { return true; } - Set> caseExpressions = switchElement.getCases().stream().flatMap(cases -> cases.getCaseExpressions().stream()).collect(Collectors.toSet()); if (switchElement.getSelector().getType().isEnum()) { + Set> caseExpressions = switchElement.getCases().stream().flatMap(cases -> cases.getCaseExpressions().stream()).collect(Collectors.toSet()); CtEnum enumType = (CtEnum) switchElement.getSelector().getType().getTypeDeclaration(); Set enumConstantNames = enumType.getEnumValues().stream().map(CtEnumValue::getSimpleName).collect(Collectors.toSet()); Set referencedEnumConstants = caseExpressions.stream().map(expression -> ((CtFieldRead) expression).getVariable().getSimpleName()).collect(Collectors.toSet()); - if (referencedEnumConstants.containsAll(enumConstantNames)) { - return true; - } + return referencedEnumConstants.containsAll(enumConstantNames); } - // TODO: More complete exhaustive check - return false; + CtTypeReference selectorTypeReference = switchElement.getSelector().getType(); + + boolean isEnhanced = !selectorTypeReference.isPrimitive() && !selectorTypeReference.equals(selectorTypeReference.getFactory().Type().createReference(String.class)); + + return isEnhanced; } @Override diff --git a/spoon-control-flow/src/test/java/fr/inria/controlflow/ForwardFlowBuilderVisitorTest.java b/spoon-control-flow/src/test/java/fr/inria/controlflow/ForwardFlowBuilderVisitorTest.java index 0dfb1a73451..752f27d7af9 100644 --- a/spoon-control-flow/src/test/java/fr/inria/controlflow/ForwardFlowBuilderVisitorTest.java +++ b/spoon-control-flow/src/test/java/fr/inria/controlflow/ForwardFlowBuilderVisitorTest.java @@ -267,6 +267,16 @@ public void testEnhancedSwitchImplicitDefault() throws Exception { assertEquals(2, paths.size()); } + @Test + public void testEnhancedSwitchImplicitDefaultString() throws Exception { + ControlFlowGraph graph = testMethod("enhancedSwitchImplicitDefaultString", true, null, null, null); + graph.simplify(); + ControlFlowPathHelper pathHelper = new ControlFlowPathHelper(); + ControlFlowNode entryNode = graph.findNodesOfKind(BEGIN).get(0); + List> paths = pathHelper.paths(entryNode); + assertEquals(2, paths.size()); + } + @Test public void testEnhancedSwitchMultipleExpressions() throws Exception { ControlFlowGraph graph = testMethod("enhancedSwitchMultipleExpressions", true, null, null, null); @@ -344,17 +354,7 @@ public void testComplexSealedHierarchyExhaustive() throws Exception { ControlFlowPathHelper pathHelper = new ControlFlowPathHelper(); ControlFlowNode entryNode = graph.findNodesOfKind(BEGIN).get(0); List> paths = pathHelper.paths(entryNode); - assertEquals(2, paths.size()); - } - - @Test - public void testEnhancedSwitchExhaustiveParametrization() throws Exception { - ControlFlowGraph graph = testMethod("enhancedSwitchExhaustiveParametrization", true, null, null, null); - graph.simplify(); - ControlFlowPathHelper pathHelper = new ControlFlowPathHelper(); - ControlFlowNode entryNode = graph.findNodesOfKind(BEGIN).get(0); - List> paths = pathHelper.paths(entryNode); - assertEquals(1, paths.size()); + assertEquals(3, paths.size()); } } diff --git a/spoon-control-flow/src/test/resources/control-flow/ControlFlowArithmetic.java b/spoon-control-flow/src/test/resources/control-flow/ControlFlowArithmetic.java index 779aaf57156..3ec4e4849a2 100644 --- a/spoon-control-flow/src/test/resources/control-flow/ControlFlowArithmetic.java +++ b/spoon-control-flow/src/test/resources/control-flow/ControlFlowArithmetic.java @@ -447,6 +447,16 @@ public void enhancedSwitchImplicitDefault() { } } + public void enhancedSwitchImplicitDefaultString() { + int a = 1; + int b = 0; + switch ("a") { + case "1" -> { + b = 1; + } + } + } + public void enhancedSwitchMultipleExpressions() { switch (3) { case 1, 2 -> { @@ -503,11 +513,11 @@ final class B extends A { final class C extends A { } - static int enhancedSwitchSealedExhaustive(I i) { + static void enhancedSwitchSealedExhaustive(I i) { switch (i) { case A a -> {} case R r -> {} - }; + } } static int enhancedSwitchExhaustiveConstantTrueGuard(I i) { @@ -525,15 +535,6 @@ static int enhancedSwitchMultilevelSealedExhaustive(I i) { }; } - sealed interface J permits D, E {} - final class D implements J {} - final class E implements J {} - - static int enhancedSwitchExhaustiveParametrization(J ji) { - switch(ji) { // Exhaustive! - case E e -> 42; - }; - } //All lines will be tested in this method public int simple(int a) {