diff --git a/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_symboltable/serialization/ScopeDeSerDecorator.java b/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_symboltable/serialization/ScopeDeSerDecorator.java index b0194c2bb..f94ebbb3c 100644 --- a/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_symboltable/serialization/ScopeDeSerDecorator.java +++ b/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_symboltable/serialization/ScopeDeSerDecorator.java @@ -301,7 +301,8 @@ protected Map createSymbolMap(ASTCDDefinition symbolInput) { //add local symbols for (ASTCDType prod : symbolTableService.getSymbolDefiningProds(symbolInput)) { String name = symbolTableService.getSymbolFullName(prod); - boolean spansScope = symbolTableService.hasScopeStereotype(prod.getModifier()); + boolean spansScope = symbolTableService.hasScopeStereotype(prod.getModifier()) + || symbolTableService.hasInheritedScopeStereotype(prod.getModifier()); symbolMap.put(name, spansScope); } @@ -311,8 +312,8 @@ protected Map createSymbolMap(ASTCDDefinition symbolInput) { if (type.isPresentAstNode() && symbolTableService.hasSymbolStereotype(type.getAstNode().getModifier())) { String name = symbolTableService .getSymbolFullName(type.getAstNode(), cdDefinitionSymbol); - boolean spansScope = symbolTableService - .hasScopeStereotype(type.getAstNode().getModifier()); + boolean spansScope = symbolTableService.hasScopeStereotype(type.getAstNode().getModifier()) + || symbolTableService.hasInheritedScopeStereotype(type.getAstNode().getModifier()); symbolMap.put(name, spansScope); } } diff --git a/monticore-grammar/src/main/grammars/de/monticore/symbols/OOSymbols.mc4 b/monticore-grammar/src/main/grammars/de/monticore/symbols/OOSymbols.mc4 index 0eef9b696..a18843f41 100644 --- a/monticore-grammar/src/main/grammars/de/monticore/symbols/OOSymbols.mc4 +++ b/monticore-grammar/src/main/grammars/de/monticore/symbols/OOSymbols.mc4 @@ -89,7 +89,7 @@ component grammar OOSymbols extends BasicSymbols { * The new symbol MethodSymbol inherits from FunctionSymbol and * mainly adds OO specific properties. */ - interface scope symbol Method extends Function = Name ; + interface symbol Method extends Function = Name ; symbolrule Method = isConstructor: boolean diff --git a/monticore-test/01.experiments/stcomposition01/src/main/grammars/SystematicScopeDeSer.mc4 b/monticore-test/01.experiments/stcomposition01/src/main/grammars/SystematicScopeDeSer.mc4 new file mode 100644 index 000000000..38b287a58 --- /dev/null +++ b/monticore-test/01.experiments/stcomposition01/src/main/grammars/SystematicScopeDeSer.mc4 @@ -0,0 +1,27 @@ +/* (c) https://github.com/MontiCore/monticore */ +grammar SystematicScopeDeSer extends de.monticore.MCBasics, de.monticore.symbols.OOSymbols { + + CompilationUnit = MyScopeSymbolI* Method* Function*; + start CompilationUnit; + + // Defines scope & interface + interface symbol scope MyScopeSymbolI = Name; + + // In the symbol table, this is actually a MyScopeSymbolI + interface MyScopeSymbolI2 extends MyScopeSymbolI = Name; + + // All of the following productions are symbols which span a scope + // Some explicitly define a "new" symbol, while others are MyScopeSymbolI-symbols + MyScopeSymbolIImpl1 implements MyScopeSymbolI = Name; // MyScopeSymbolI symbol + symbol MyScopeSymbolIImpl2 implements MyScopeSymbolI = Name; // new symbol + symbol scope MyScopeSymbolIImpl3 implements MyScopeSymbolI = Name; // new symbol + + MyScopeSymbolI2Impl1 implements MyScopeSymbolI2 = Name; // MyScopeSymbolI symbol + symbol MyScopeSymbolI2Impl2 implements MyScopeSymbolI2 = Name; // new symbol + symbol scope MyScopeSymbolI2Impl3 implements MyScopeSymbolI2 = Name; // new symbol + + // Also test using OO/Basic symbols + TestMethod implements Method = "method" Name; + TestFunction implements Function = "function" Name; + +} diff --git a/monticore-test/01.experiments/stcomposition01/src/test/java/SystematicDeSerTest.java b/monticore-test/01.experiments/stcomposition01/src/test/java/SystematicDeSerTest.java new file mode 100644 index 000000000..36c701e25 --- /dev/null +++ b/monticore-test/01.experiments/stcomposition01/src/test/java/SystematicDeSerTest.java @@ -0,0 +1,93 @@ +/* (c) https://github.com/MontiCore/monticore */ +import de.monticore.symbols.basicsymbols._symboltable.FunctionSymbol; +import de.monticore.symbols.oosymbols._symboltable.MethodSymbol; +import de.monticore.types.check.SymTypeObscure; +import de.se_rwth.commons.logging.LogStub; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import systematicscopedeser.SystematicScopeDeSerMill; +import systematicscopedeser._symboltable.*; + +/** + * Test that the DeSer correctly handles inherited scope/symbols + * as well as their subscopes + */ +public class SystematicDeSerTest { + + @BeforeAll + public static void init() { + LogStub.init(); + LogStub.clearFindings(); + + SystematicScopeDeSerMill.init(); + } + + @Test + public void test() { + // Construct one of each symbol + var compU = SystematicScopeDeSerMill.compilationUnitBuilder(); + + // direct implementations of interface symbol scope MyScopeSymbolI + var i1 = SystematicScopeDeSerMill.myScopeSymbolIImpl1Builder().setName("i1").build(); + compU.addMyScopeSymbolI(i1); + var i2 = SystematicScopeDeSerMill.myScopeSymbolIImpl2Builder().setName("i2").build(); + compU.addMyScopeSymbolI(i2); + var i3 = SystematicScopeDeSerMill.myScopeSymbolIImpl3Builder().setName("i3").build(); + compU.addMyScopeSymbolI(i3); + + // indirect implementations of interface MyScopeSymbolI2 extends MyScopeSymbolI + var s1 = SystematicScopeDeSerMill.myScopeSymbolI2Impl1Builder().setName("s1").build(); + compU.addMyScopeSymbolI(s1); + var s2 = SystematicScopeDeSerMill.myScopeSymbolI2Impl2Builder().setName("s2").build(); + compU.addMyScopeSymbolI(s2); + var s3 = SystematicScopeDeSerMill.myScopeSymbolI2Impl3Builder().setName("s3").build(); + compU.addMyScopeSymbolI(s3); + var m = SystematicScopeDeSerMill.testMethodBuilder().setName("m").build(); + compU.addMethod(m); + var f = SystematicScopeDeSerMill.testFunctionBuilder().setName("f").build(); + compU.addFunction(f); + + var ast = compU.build(); + + var scope = SystematicScopeDeSerMill.scopesGenitorDelegator().createFromAST(ast); + + // Set some SymTypeExpression information for the type field + m.getSymbol().setType(new SymTypeObscure()); + f.getSymbol().setType(new SymTypeObscure()); + + Assertions.assertEquals(8, scope.getSubScopes().size()); + // Test that the symbols are correct + Assertions.assertEquals(MyScopeSymbolISymbol.class, i1.getSymbol().getClass()); + Assertions.assertEquals(MyScopeSymbolIImpl2Symbol.class, i2.getSymbol().getClass()); + Assertions.assertEquals(MyScopeSymbolIImpl3Symbol.class, i3.getSymbol().getClass()); + Assertions.assertEquals(MyScopeSymbolISymbol.class, s1.getSymbol().getClass()); + Assertions.assertEquals(MyScopeSymbolI2Impl2Symbol.class, s2.getSymbol().getClass()); + Assertions.assertEquals(MyScopeSymbolI2Impl3Symbol.class, s3.getSymbol().getClass()); + Assertions.assertEquals(MethodSymbol.class, m.getSymbol().getClass()); + Assertions.assertEquals(FunctionSymbol.class, f.getSymbol().getClass()); + + var s2j = new SystematicScopeDeSerSymbols2Json(); + + String serialized = s2j.serialize(scope); + + // And now, do similar tests on the serialized & deserialized symbol table + + var scope2 = s2j.deserialize(serialized); + + Assertions.assertEquals(8, scope2.getSubScopes().size()); + // Test that the symbols are present && correct + Assertions.assertEquals(MyScopeSymbolISymbol.class, scope2.resolveMyScopeSymbolI("i1").get().getClass()); + Assertions.assertEquals(MyScopeSymbolIImpl2Symbol.class, scope2.resolveMyScopeSymbolIImpl2("i2").get().getClass()); + Assertions.assertEquals(MyScopeSymbolIImpl3Symbol.class, scope2.resolveMyScopeSymbolIImpl3("i3").get().getClass()); + Assertions.assertEquals(MyScopeSymbolISymbol.class, scope2.resolveMyScopeSymbolI("s1").get().getClass()); + Assertions.assertEquals(MyScopeSymbolI2Impl2Symbol.class, scope2.resolveMyScopeSymbolI2Impl2("s2").get().getClass()); + Assertions.assertEquals(MyScopeSymbolI2Impl3Symbol.class, scope2.resolveMyScopeSymbolI2Impl3("s3").get().getClass()); + Assertions.assertEquals(MethodSymbol.class, scope2.resolveMethod("m").get().getClass()); + Assertions.assertEquals(FunctionSymbol.class, scope2.resolveFunction("f").get().getClass()); + + Assertions.assertTrue(LogStub.getFindings().isEmpty()); + } + + +}