From 9b223a767b7d40315940f716d48886968d2364bc Mon Sep 17 00:00:00 2001 From: n_jansen Date: Wed, 9 Oct 2024 12:32:55 +0200 Subject: [PATCH] Fix duplicate traversal in inheritance traversing for overridden nodes. --- .../_visitor/InheritanceHandlerDecorator.java | 6 ++-- .../main/grammars/mc/feature/visitor/Sub.mc4 | 5 +++- .../main/grammars/mc/feature/visitor/Sup.mc4 | 4 +++ .../java/mc/feature/visitor/NodeCounter.java | 25 ++++++++++++++++ .../java/mc/feature/visitor/VisitorTest.java | 30 +++++++++++++++++++ 5 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 monticore-test/it/src/main/java/mc/feature/visitor/NodeCounter.java diff --git a/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_visitor/InheritanceHandlerDecorator.java b/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_visitor/InheritanceHandlerDecorator.java index 753ba97ddf..40d59dc012 100644 --- a/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_visitor/InheritanceHandlerDecorator.java +++ b/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_visitor/InheritanceHandlerDecorator.java @@ -20,7 +20,9 @@ import de.se_rwth.commons.Joiners; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import static de.monticore.cd.codegen.CD2JavaTemplates.ANNOTATIONS; @@ -100,10 +102,10 @@ protected List getASTHandleMethods(ASTCDDefinition astcdDefinition, protected ASTCDMethod getASTHandleMethod(ASTCDClass astcdClass, String languageInterfaceName, String handlerSimpleTypeName) { ASTCDMethod handleMethod = visitorService.getVisitorMethod(HANDLE, getMCTypeFacade().createQualifiedType(Joiners.DOT.join(visitorService.getASTPackage(), astcdClass.getName()))); - List superTypeList = new ArrayList<>(); + Set superTypeList = new LinkedHashSet<>(); // super classes if (astcdClass.isPresentCDExtendUsage() && !astcdClass.printSuperclasses().isEmpty()) { - superTypeList= visitorService.getAllSuperClassesTransitive(astcdClass); + superTypeList.addAll(visitorService.getAllSuperClassesTransitive(astcdClass)); } // super interfaces superTypeList.addAll(visitorService.getAllSuperInterfacesTransitive(astcdClass.getSymbol())); diff --git a/monticore-test/it/src/main/grammars/mc/feature/visitor/Sub.mc4 b/monticore-test/it/src/main/grammars/mc/feature/visitor/Sub.mc4 index 66a9636e57..b7590f63e0 100644 --- a/monticore-test/it/src/main/grammars/mc/feature/visitor/Sub.mc4 +++ b/monticore-test/it/src/main/grammars/mc/feature/visitor/Sub.mc4 @@ -6,6 +6,9 @@ grammar Sub extends mc.feature.visitor.Sup { E = B; - B = "test2"; + B = "test2" NodeImpl?; + + @Override + NodeImpl implements SomeNode = "NodeOverride"; } diff --git a/monticore-test/it/src/main/grammars/mc/feature/visitor/Sup.mc4 b/monticore-test/it/src/main/grammars/mc/feature/visitor/Sup.mc4 index 23fd84ba8c..4d5c8a8dbf 100644 --- a/monticore-test/it/src/main/grammars/mc/feature/visitor/Sup.mc4 +++ b/monticore-test/it/src/main/grammars/mc/feature/visitor/Sup.mc4 @@ -8,4 +8,8 @@ component grammar Sup extends mc.common.Basics { A = "test1" E; + interface SomeNode; + + NodeImpl implements SomeNode = "NodeImpl"; + } diff --git a/monticore-test/it/src/main/java/mc/feature/visitor/NodeCounter.java b/monticore-test/it/src/main/java/mc/feature/visitor/NodeCounter.java new file mode 100644 index 0000000000..a55ea64e6e --- /dev/null +++ b/monticore-test/it/src/main/java/mc/feature/visitor/NodeCounter.java @@ -0,0 +1,25 @@ +/* (c) https://github.com/MontiCore/monticore */ + +package mc.feature.visitor; + +import mc.feature.visitor.sup._ast.ASTSomeNode; +import mc.feature.visitor.sup._visitor.SupVisitor2; + +public class NodeCounter implements SupVisitor2 { + + protected int num = 0; + + @Override + public void visit(ASTSomeNode node) { + num++; + } + + public int getNum() { + return num; + } + + public void setNum(int num) { + this.num = num; + } + +} diff --git a/monticore-test/it/src/test/java/mc/feature/visitor/VisitorTest.java b/monticore-test/it/src/test/java/mc/feature/visitor/VisitorTest.java index 7bae339de1..a08235bdb4 100644 --- a/monticore-test/it/src/test/java/mc/feature/visitor/VisitorTest.java +++ b/monticore-test/it/src/test/java/mc/feature/visitor/VisitorTest.java @@ -18,6 +18,7 @@ import de.se_rwth.commons.logging.Log; import mc.GeneratorIntegrationsTest; import mc.feature.visitor.sub.SubMill; +import mc.feature.visitor.sub._ast.ASTE; import mc.feature.visitor.sub._parser.SubParser; import mc.feature.visitor.sub._visitor.SubTraverser; import mc.feature.visitor.sup._ast.ASTA; @@ -58,4 +59,33 @@ public void testConcreteVisitor() throws IOException { Assertions.assertTrue(Log.getFindings().isEmpty()); } + + @Test + public void testInheritanceTraversal() throws IOException { + SubParser p = new SubParser(); + Optional node = p.parse_String("test2 NodeOverride"); + Assertions.assertFalse(p.hasErrors()); + Assertions.assertTrue(node.isPresent()); + + // init with plain traverser + SubTraverser t1 = SubMill.traverser(); + NodeCounter c1 = new NodeCounter(); + t1.add4Sup(c1); + + // plain traverser should not reach the interface implementation + node.get().accept(t1); + Assertions.assertEquals(0, c1.getNum()); + + + // init with inheritance traverser + SubTraverser t2 = SubMill.inheritanceTraverser(); + NodeCounter c2 = new NodeCounter(); + t2.add4Sup(c2); + + // inheritance traverser should reach the interface implementation precisely once + node.get().accept(t2); + Assertions.assertEquals(1, c2.getNum()); + + } + }