diff --git a/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeClassDecorator.java b/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeClassDecorator.java index 0ba61321c0..97729065f3 100644 --- a/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeClassDecorator.java +++ b/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeClassDecorator.java @@ -27,14 +27,12 @@ import de.monticore.types.mcsimplegenerictypes._ast.ASTMCBasicGenericType; import de.se_rwth.commons.Names; import de.se_rwth.commons.StringTransformations; - import java.util.*; import java.util.stream.Collectors; import static de.monticore.cd.codegen.CD2JavaTemplates.EMPTY_BODY; import static de.monticore.cd.codegen.CD2JavaTemplates.VALUE; -import static de.monticore.cd.facade.CDModifier.PROTECTED; -import static de.monticore.cd.facade.CDModifier.PUBLIC; +import static de.monticore.cd.facade.CDModifier.*; import static de.monticore.codegen.cd2java._ast.ast_class.ASTConstants.AST_INTERFACE; import static de.monticore.codegen.cd2java._symboltable.SymbolTableConstants.*; import static de.monticore.codegen.cd2java._visitor.VisitorConstants.VISITOR_PREFIX; @@ -123,7 +121,7 @@ public ASTCDClass decorate(ASTCDCompilationUnit scopeInput, ASTCDCompilationUnit symbolInput.getCDDefinition().getCDClassesList(), symbolTableService.getCDSymbol()); symbolAttributes.putAll(getSuperSymbolAttributes()); - List symbolMethods = createSymbolMethods(symbolAttributes.values()); + List symbolMethods = createSymbolMethods(symbolAttributes.values(), symbolInput.getCDDefinition()); List symbolAlreadyResolvedAttributes = createSymbolAlreadyResolvedAttributes( symbolAttributes.keySet()); @@ -300,7 +298,7 @@ protected Map createSymbolAttributes( } /** - * only returns a attribute if the cdType really defines a symbol + * only returns an attribute if the cdType really defines a symbol */ protected Optional createSymbolAttribute(ASTCDType cdType, DiagramSymbol cdDefinitionSymbol) { @@ -334,7 +332,7 @@ protected List createSymbolAlreadyResolvedAttributes( return symbolAttributeList; } - protected List createSymbolMethods(Collection astcdAttributes) { + protected List createSymbolMethods(Collection astcdAttributes, ASTCDDefinition symbolInput) { List symbolMethodList = new ArrayList<>(); for (ASTCDAttribute attribute : astcdAttributes) { if (attribute.getMCType() instanceof ASTMCBasicGenericType @@ -345,6 +343,7 @@ protected List createSymbolMethods(Collection astcd symbolMethodList.add(createAddSymbolMethod(mcTypeArgument.get(), attribute.getName())); symbolMethodList.add(createRemoveSymbolMethod(mcTypeArgument.get(), attribute.getName())); symbolMethodList.add(createGetSymbolListMethod(attribute)); + symbolMethodList.add(createGetSymbolsWithSubKindsMethod(attribute, symbolInput)); } } } @@ -377,6 +376,41 @@ protected ASTCDMethod createGetSymbolListMethod(ASTCDAttribute astcdAttribute) { return method; } + protected ASTCDMethod createGetSymbolsWithSubKindsMethod(ASTCDAttribute astcdAttribute, ASTCDDefinition symbolDefinition) { + ASTMCType returnType = astcdAttribute.getMCType(); + ASTCDAttribute returnAttribute = getCDAttributeFacade() + .createAttribute(PROTECTED.build(), returnType, astcdAttribute.getName()); + + ASTCDMethod method = getCDMethodFacade().createMethod(PUBLIC.build(), returnAttribute.getMCType(), + "get" + StringTransformations.capitalize(astcdAttribute.getName())+"WithSubKinds"); + + //calculate subkindsMap for the symbol + Set result = new HashSet<>(); + List symbols = symbolTableService.getSymbolDefiningProds(symbolDefinition); + symbols.addAll(symbolTableService.getSymbolDefiningSuperProds()); + ListMultimap subKinds = SymbolKindHierarchies + .calculateSubKinds(symbols, symbolTableService); + + //get names of attribute and check the subkindsMap for them recursively + List lastAttributeNames = new ArrayList<>(); + //as all attribute come in the Form Symbols, + // we need to cut the Symbols part away and capitalize the first letter + lastAttributeNames.add(StringTransformations.capitalize(symbolTableService.getSimpleNameFromSymbolName(astcdAttribute.getName()))); + while (!lastAttributeNames.isEmpty()){ + List newAttributeNames = new ArrayList<>(); + for(String s: lastAttributeNames){ + //get all subkinds that match the same string key as the attribute + newAttributeNames.addAll(subKinds.get(s)); + result.addAll(subKinds.get(s)); + } + lastAttributeNames = newAttributeNames; + } + + this.replaceTemplate(EMPTY_BODY, method, new TemplateHookPoint(TEMPLATE_PATH + "GetSymbolsWithSubKinds", + StringTransformations.capitalize(astcdAttribute.getName()), returnAttribute.getMCType().printType(), result)); + return method; + } + protected ASTCDAttribute createEnclosingScopeAttribute() { ASTCDAttribute attribute = this.getCDAttributeFacade() .createAttribute(PROTECTED.build(), symbolTableService.getScopeInterfaceType(), diff --git a/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeInterfaceDecorator.java b/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeInterfaceDecorator.java index f1b6f81b86..6398ac74c2 100644 --- a/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeInterfaceDecorator.java +++ b/monticore-generator/src/main/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeInterfaceDecorator.java @@ -30,7 +30,6 @@ import de.se_rwth.commons.Joiners; import de.se_rwth.commons.Names; import de.se_rwth.commons.StringTransformations; - import java.util.*; import java.util.stream.Collectors; @@ -259,6 +258,10 @@ protected List createScopeInterfaceMethodsForSymbols(List +${tc.signature("fullSymbolName", "fullSymbolType", "allSymbolSubKinds")} + ${fullSymbolType} symbols = com.google.common.collect.LinkedListMultimap.create(); + symbols.putAll(get${fullSymbolName}()); +<#list allSymbolSubKinds as subKind> + symbols.putAll(get${subKind}Symbols()); + + return symbols; \ No newline at end of file diff --git a/monticore-generator/src/test/java/de/monticore/codegen/cd2java/DecoratorTestUtil.java b/monticore-generator/src/test/java/de/monticore/codegen/cd2java/DecoratorTestUtil.java index eeece230fd..ae9dec508e 100644 --- a/monticore-generator/src/test/java/de/monticore/codegen/cd2java/DecoratorTestUtil.java +++ b/monticore-generator/src/test/java/de/monticore/codegen/cd2java/DecoratorTestUtil.java @@ -90,6 +90,14 @@ public static List getMethodsBy(String name, int parameterSize, Lis m -> parameterSize == m.getCDParameterList().size())); } + public static List getMethodsBy(List methods, List> predicates) { + return filterMethods(methods, predicates); + } + + public static ASTCDMethod getMethodBy(List methods, List> predicates) { + return filterMethodsOrFail(methods, predicates); + } + public static ASTCDMethod getMethodBy(String name, List methods) { return filterMethodsOrFail(methods, Collections.singletonList( m -> name.equals(m.getName()))); diff --git a/monticore-generator/src/test/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeClassDecoratorTest.java b/monticore-generator/src/test/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeClassDecoratorTest.java index 4e9b928a16..65751a1315 100644 --- a/monticore-generator/src/test/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeClassDecoratorTest.java +++ b/monticore-generator/src/test/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeClassDecoratorTest.java @@ -23,10 +23,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; +import java.util.function.Predicate; + import static de.monticore.cd.facade.CDModifier.PROTECTED; import static de.monticore.cd.facade.CDModifier.PUBLIC; @@ -60,6 +59,8 @@ public class ScopeClassDecoratorTest extends DecoratorTestCase { private static final String QUALIFIED_NAME_SYMBOL_MAP = "com.google.common.collect.LinkedListMultimap"; + private static final String UNKNOWN_SYMBOL_MAP = "com.google.common.collect.LinkedListMultimap"; + private static final String FOO_SYMBOL_MAP = "com.google.common.collect.LinkedListMultimap"; private static final String AUTOMATON_SYMBOL = "de.monticore.codegen.symboltable.automaton._symboltable.AutomatonSymbol"; @@ -83,7 +84,6 @@ public class ScopeClassDecoratorTest extends DecoratorTestCase { @BeforeEach public void setUp() { this.mcTypeFacade = mcTypeFacade.getInstance(); - ASTCDCompilationUnit astcdCompilationUnit = this.parse("de", "monticore", "codegen", "symboltable", "Automaton"); decoratedSymbolCompilationUnit = this.parse("de", "monticore", "codegen", "symboltable", "AutomatonSymbolCD"); decoratedScopeCompilationUnit = this.parse("de", "monticore", "codegen", "symboltable", "AutomatonScopeCD"); @@ -375,7 +375,7 @@ public void testScopeRuleAttributes() { @Test public void testMethodCount() { - assertEquals(99, scopeClass.getCDMethodList().size()); + assertEquals(104, scopeClass.getCDMethodList().size()); assertTrue(Log.getFindings().isEmpty()); } @@ -467,8 +467,6 @@ public void testAddSymbolMethod() { assertTrue(Log.getFindings().isEmpty()); } - - @Test public void testGetAutomatonSymbolsMethod() { ASTCDMethod method = getMethodBy("getAutomatonSymbols", scopeClass); @@ -481,6 +479,46 @@ public void testGetAutomatonSymbolsMethod() { assertTrue(Log.getFindings().isEmpty()); } + @Test + public void testGetSymbolWithSubKindsMethod() { + List> predicates = Arrays.asList( + m -> m.getName().endsWith("WithSubKinds") + ); + List methodList = getMethodsBy(scopeClass.getCDMethodList(), predicates); + Map methods = new HashMap<>(); + methodList.forEach(l -> methods.put( + CD4CodeMill.prettyPrint(l.getMCReturnType().getMCType(), false), l) + ); + + assertEquals(5, methodList.size()); + + ASTCDMethod automatonAdd = methods.get(AUTOMATON_SYMBOL_MAP); + assertDeepEquals(PUBLIC, automatonAdd.getModifier()); + assertTrue(automatonAdd.isEmptyCDParameters()); + assertEquals("getAutomatonSymbolsWithSubKinds", automatonAdd.getName()); + + ASTCDMethod stateAdd = methods.get(STATE_SYMBOL_MAP); + assertDeepEquals(PUBLIC, stateAdd.getModifier()); + assertTrue(stateAdd.isEmptyCDParameters()); + assertEquals("getStateSymbolsWithSubKinds", stateAdd.getName()); + + ASTCDMethod qualifiedNameAdd = methods.get(QUALIFIED_NAME_SYMBOL_MAP); + assertDeepEquals(PUBLIC, qualifiedNameAdd.getModifier()); + assertTrue(qualifiedNameAdd.isEmptyCDParameters()); + assertEquals("getQualifiedNameSymbolsWithSubKinds", qualifiedNameAdd.getName()); + + ASTCDMethod unknownAdd = methods.get(UNKNOWN_SYMBOL_MAP); + assertDeepEquals(PUBLIC, unknownAdd.getModifier()); + assertTrue(unknownAdd.isEmptyCDParameters()); + assertEquals("getUnknownSymbolsWithSubKinds", unknownAdd.getName()); + + ASTCDMethod fooAdd = methods.get(FOO_SYMBOL_MAP); + assertDeepEquals(PUBLIC, fooAdd.getModifier()); + assertTrue(fooAdd.isEmptyCDParameters()); + assertEquals("getFooSymbolsWithSubKinds", fooAdd.getName()); + + assertTrue(Log.getFindings().isEmpty()); + } @Test public void testGetStateSymbolsMethod() { diff --git a/monticore-generator/src/test/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeInterfaceDecoratorTest.java b/monticore-generator/src/test/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeInterfaceDecoratorTest.java index 4693d22ae8..0dd28ebe4e 100644 --- a/monticore-generator/src/test/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeInterfaceDecoratorTest.java +++ b/monticore-generator/src/test/java/de/monticore/codegen/cd2java/_symboltable/scope/ScopeInterfaceDecoratorTest.java @@ -6,6 +6,7 @@ import com.github.javaparser.ParserConfiguration; import de.monticore.cd.codegen.CD2JavaTemplates; import de.monticore.cd.methodtemplates.CD4C; +import de.monticore.cd4code.CD4CodeMill; import de.monticore.cd4codebasis._ast.ASTCDMethod; import de.monticore.cdbasis._ast.ASTCDCompilationUnit; import de.monticore.cdinterfaceandenum._ast.ASTCDInterface; @@ -17,11 +18,13 @@ import de.monticore.generating.GeneratorEngine; import de.monticore.generating.GeneratorSetup; import de.se_rwth.commons.logging.Log; +import java.util.Arrays; +import java.util.HashMap; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; - import java.util.List; - +import java.util.Map; +import java.util.function.Predicate; import static de.monticore.cd.facade.CDModifier.PUBLIC; import static de.monticore.cd.facade.CDModifier.PUBLIC_ABSTRACT; import static de.monticore.codegen.cd2java.DecoratorAssert.assertBoolean; @@ -35,9 +38,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class ScopeInterfaceDecoratorTest extends DecoratorTestCase { + private ASTCDInterface scopeInterface; - private de.monticore.types.MCTypeFacade MCTypeFacade; + private de.monticore.types.MCTypeFacade mcTypeFacade; private ASTCDCompilationUnit decoratedScopeCompilationUnit; @@ -49,6 +53,14 @@ public class ScopeInterfaceDecoratorTest extends DecoratorTestCase { private static final String I_LEXICAS_SCOPE = "de.monticore.codegen.ast.lexicals._symboltable.ILexicalsScope"; + private static final String I_NOTASYMBOL_SYMBOL_MAP = "com.google.common.collect.LinkedListMultimap"; + + private static final String I_STATES_SYMBOL_MAP = "com.google.common.collect.LinkedListMultimap"; + + private static final String I_AUTOMATON_SYMBOL_MAP = "com.google.common.collect.LinkedListMultimap"; + + private static final String I_FOO_SYMBOL_MAP = "com.google.common.collect.LinkedListMultimap"; + private static final String ACCESS_MODIFIER = "de.monticore.symboltable.modifiers.AccessModifier"; private static final String PREDICATE = "java.util.function.Predicate"; @@ -56,9 +68,9 @@ public class ScopeInterfaceDecoratorTest extends DecoratorTestCase { @BeforeEach public void setUp() { - this.MCTypeFacade = MCTypeFacade.getInstance(); + this.mcTypeFacade = mcTypeFacade.getInstance(); ASTCDCompilationUnit astcdCompilationUnit = this.parse("de", "monticore", "codegen", "symboltable", "Automaton"); - ASTCDCompilationUnit symbolCd = this.parse("de", "monticore", "codegen", "symboltable", "AutomatonSymbolCD"); + ASTCDCompilationUnit decoratedSymbolCompilationUnit = this.parse("de", "monticore", "codegen", "symboltable", "AutomatonSymbolCD"); decoratedScopeCompilationUnit = this.parse("de", "monticore", "codegen", "symboltable", "AutomatonScopeCD"); originalCompilationUnit = decoratedScopeCompilationUnit.deepClone(); this.glex.setGlobalValue("service", new AbstractService(astcdCompilationUnit)); @@ -67,7 +79,7 @@ public void setUp() { new VisitorService(astcdCompilationUnit), new MethodDecorator(glex, new SymbolTableService(astcdCompilationUnit))); //creates normal Symbol - this.scopeInterface = decorator.decorate(decoratedScopeCompilationUnit, symbolCd); + this.scopeInterface = decorator.decorate(decoratedScopeCompilationUnit, decoratedSymbolCompilationUnit); } @Test @@ -108,11 +120,45 @@ public void testNoAttributes() { @Test public void testMethodCount() { - assertEquals(168, scopeInterface.getCDMethodList().size()); + assertEquals(172, scopeInterface.getCDMethodList().size()); assertTrue(Log.getFindings().isEmpty()); } + @Test + public void testGetSymbolWithSubKinds() { + List> predicates = Arrays.asList( + m -> m.getName().endsWith("WithSubKinds") + ); + List methodList = getMethodsBy(scopeInterface.getCDMethodList(), predicates); + Map methods = new HashMap<>(); + methodList.forEach(l -> methods.put( + CD4CodeMill.prettyPrint(l.getMCReturnType().getMCType(), false), l) + ); + + assertEquals(4, methodList.size()); + + ASTCDMethod methodQualifiedName = methods.get(I_NOTASYMBOL_SYMBOL_MAP); + assertDeepEquals(PUBLIC_ABSTRACT, methodQualifiedName.getModifier()); + assertEquals(I_NOTASYMBOL_SYMBOL_MAP, methodQualifiedName.getMCReturnType().printType()); + assertEquals(0, methodQualifiedName.sizeCDParameters()); + + ASTCDMethod methodGetUnknown = methods.get(I_STATES_SYMBOL_MAP); + assertDeepEquals(PUBLIC_ABSTRACT, methodGetUnknown.getModifier()); + assertEquals(I_STATES_SYMBOL_MAP, methodGetUnknown.getMCReturnType().printType()); + assertEquals(0, methodGetUnknown.sizeCDParameters()); + + ASTCDMethod methodGetFoo = methods.get(I_AUTOMATON_SYMBOL_MAP); + assertDeepEquals(PUBLIC_ABSTRACT, methodGetFoo.getModifier()); + assertEquals(I_AUTOMATON_SYMBOL_MAP, methodGetFoo.getMCReturnType().printType()); + assertEquals(0, methodGetFoo.sizeCDParameters()); + + ASTCDMethod methodGetState = methods.get(I_FOO_SYMBOL_MAP); + assertDeepEquals(PUBLIC_ABSTRACT, methodGetState.getModifier()); + assertEquals(I_FOO_SYMBOL_MAP, methodGetState.getMCReturnType().printType()); + assertEquals(0, methodGetState.sizeCDParameters()); + } + @Test public void testIsStateSymbolsAlreadyResolvedMethod() { ASTCDMethod method = getMethodBy("isStateSymbolsAlreadyResolved", scopeInterface); @@ -171,7 +217,7 @@ public void testResolveAutomaton1ParamMethod() { ASTCDMethod resolveName = methodList.get(0); assertDeepEquals(PUBLIC, resolveName.getModifier()); - assertDeepEquals(MCTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), resolveName.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), resolveName.getMCReturnType().getMCType()); assertEquals(1, resolveName.sizeCDParameters()); assertDeepEquals(String.class, resolveName.getCDParameter(0).getMCType()); assertEquals("name", resolveName.getCDParameter(0).getName()); @@ -187,7 +233,7 @@ public void testResolveAutomaton2ParamMethod() { ASTCDMethod resolveNameModifier = methodList.get(0); assertDeepEquals(PUBLIC, resolveNameModifier.getModifier()); - assertDeepEquals(MCTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), resolveNameModifier.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), resolveNameModifier.getMCReturnType().getMCType()); assertEquals(2, resolveNameModifier.sizeCDParameters()); assertDeepEquals(String.class, resolveNameModifier.getCDParameter(0).getMCType()); assertEquals("name", resolveNameModifier.getCDParameter(0).getName()); @@ -205,7 +251,7 @@ public void testResolveAutomaton3ParamMethod() { ASTCDMethod resoleNameModifierPredicate = methodList.get(0); assertDeepEquals(PUBLIC, resoleNameModifierPredicate.getModifier()); - assertDeepEquals(MCTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), resoleNameModifierPredicate.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), resoleNameModifierPredicate.getMCReturnType().getMCType()); assertEquals(3, resoleNameModifierPredicate.sizeCDParameters()); assertDeepEquals(String.class, resoleNameModifierPredicate.getCDParameter(0).getMCType()); assertEquals("name", resoleNameModifierPredicate.getCDParameter(0).getName()); @@ -216,7 +262,7 @@ public void testResolveAutomaton3ParamMethod() { ASTCDMethod resoleFoundSymbolsNameModifier = methodList.get(1); assertDeepEquals(PUBLIC, resoleFoundSymbolsNameModifier.getModifier()); - assertDeepEquals(MCTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), resoleFoundSymbolsNameModifier.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), resoleFoundSymbolsNameModifier.getMCReturnType().getMCType()); assertEquals(3, resoleFoundSymbolsNameModifier.sizeCDParameters()); assertBoolean(resoleFoundSymbolsNameModifier.getCDParameter(0).getMCType()); assertEquals("foundSymbols", resoleFoundSymbolsNameModifier.getCDParameter(0).getName()); @@ -237,7 +283,7 @@ public void testResolveDownAutomaton1ParamMethod() { ASTCDMethod resolveName = methodList.get(0); assertDeepEquals(PUBLIC, resolveName.getModifier()); - assertDeepEquals(MCTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), resolveName.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), resolveName.getMCReturnType().getMCType()); assertEquals(1, resolveName.sizeCDParameters()); assertDeepEquals(String.class, resolveName.getCDParameter(0).getMCType()); assertEquals("name", resolveName.getCDParameter(0).getName()); @@ -253,7 +299,7 @@ public void testResolveDownAutomaton2ParamMethod() { ASTCDMethod resolveNameModifier = methodList.get(0); assertDeepEquals(PUBLIC, resolveNameModifier.getModifier()); - assertDeepEquals(MCTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), resolveNameModifier.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), resolveNameModifier.getMCReturnType().getMCType()); assertEquals(2, resolveNameModifier.sizeCDParameters()); assertDeepEquals(String.class, resolveNameModifier.getCDParameter(0).getMCType()); assertEquals("name", resolveNameModifier.getCDParameter(0).getName()); @@ -271,7 +317,7 @@ public void testResolveDownAutomaton3ParamMethod() { ASTCDMethod resoleNameModifierPredicate = methodList.get(0); assertDeepEquals(PUBLIC, resoleNameModifierPredicate.getModifier()); - assertDeepEquals(MCTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), resoleNameModifierPredicate.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), resoleNameModifierPredicate.getMCReturnType().getMCType()); assertEquals(3, resoleNameModifierPredicate.sizeCDParameters()); assertDeepEquals(String.class, resoleNameModifierPredicate.getCDParameter(0).getMCType()); assertEquals("name", resoleNameModifierPredicate.getCDParameter(0).getName()); @@ -291,7 +337,7 @@ public void testResolveDownManyAutomaton1ParamMethod() { ASTCDMethod resolveName = methodList.get(0); assertDeepEquals(PUBLIC, resolveName.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), resolveName.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), resolveName.getMCReturnType().getMCType()); assertEquals(1, resolveName.sizeCDParameters()); assertDeepEquals(String.class, resolveName.getCDParameter(0).getMCType()); assertEquals("name", resolveName.getCDParameter(0).getName()); @@ -307,7 +353,7 @@ public void testResolveDownManyAutomaton2ParamMethod() { ASTCDMethod resolveNameModifier = methodList.get(0); assertDeepEquals(PUBLIC, resolveNameModifier.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), resolveNameModifier.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), resolveNameModifier.getMCReturnType().getMCType()); assertEquals(2, resolveNameModifier.sizeCDParameters()); assertDeepEquals(String.class, resolveNameModifier.getCDParameter(0).getMCType()); assertEquals("name", resolveNameModifier.getCDParameter(0).getName()); @@ -325,7 +371,7 @@ public void testResolveDownManyAutomaton3ParamMethod() { ASTCDMethod resoleNameModifierPredicate = methodList.get(0); assertDeepEquals(PUBLIC, resoleNameModifierPredicate.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), resoleNameModifierPredicate.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), resoleNameModifierPredicate.getMCReturnType().getMCType()); assertEquals(3, resoleNameModifierPredicate.sizeCDParameters()); assertDeepEquals(String.class, resoleNameModifierPredicate.getCDParameter(0).getMCType()); assertEquals("name", resoleNameModifierPredicate.getCDParameter(0).getName()); @@ -345,7 +391,7 @@ public void testResolveDownManyAutomaton4ParamMethod() { ASTCDMethod resoleFoundSymbolsNameModifier = methodList.get(0); assertDeepEquals(PUBLIC, resoleFoundSymbolsNameModifier.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), resoleFoundSymbolsNameModifier.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), resoleFoundSymbolsNameModifier.getMCReturnType().getMCType()); assertEquals(4, resoleFoundSymbolsNameModifier.sizeCDParameters()); assertBoolean(resoleFoundSymbolsNameModifier.getCDParameter(0).getMCType()); assertEquals("foundSymbols", resoleFoundSymbolsNameModifier.getCDParameter(0).getName()); @@ -367,7 +413,7 @@ public void testResolveManyAutomaton1ParamMethod() { ASTCDMethod resolveName = methodList.get(0); assertDeepEquals(PUBLIC, resolveName.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), resolveName.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), resolveName.getMCReturnType().getMCType()); assertEquals(1, resolveName.sizeCDParameters()); assertDeepEquals(String.class, resolveName.getCDParameter(0).getMCType()); assertEquals("name", resolveName.getCDParameter(0).getName()); @@ -383,7 +429,7 @@ public void testResolveManyAutomaton2ParamMethod() { ASTCDMethod methodModifier = methodList.get(0); assertDeepEquals(PUBLIC, methodModifier.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), methodModifier.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), methodModifier.getMCReturnType().getMCType()); assertEquals(2, methodModifier.sizeCDParameters()); assertDeepEquals(String.class, methodModifier.getCDParameter(0).getMCType()); assertEquals("name", methodModifier.getCDParameter(0).getName()); @@ -392,7 +438,7 @@ public void testResolveManyAutomaton2ParamMethod() { ASTCDMethod methodPredicate = methodList.get(1); assertDeepEquals(PUBLIC, methodPredicate.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), methodPredicate.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), methodPredicate.getMCReturnType().getMCType()); assertEquals(2, methodPredicate.sizeCDParameters()); assertDeepEquals(String.class, methodPredicate.getCDParameter(0).getMCType()); assertEquals("name", methodPredicate.getCDParameter(0).getName()); @@ -410,7 +456,7 @@ public void testResolveManyAutomaton3ParamMethod() { ASTCDMethod resoleNameModifierPredicate = methodList.get(0); assertDeepEquals(PUBLIC, resoleNameModifierPredicate.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), resoleNameModifierPredicate.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), resoleNameModifierPredicate.getMCReturnType().getMCType()); assertEquals(3, resoleNameModifierPredicate.sizeCDParameters()); assertDeepEquals(String.class, resoleNameModifierPredicate.getCDParameter(0).getMCType()); assertEquals("name", resoleNameModifierPredicate.getCDParameter(0).getName()); @@ -421,7 +467,7 @@ public void testResolveManyAutomaton3ParamMethod() { ASTCDMethod resoleFoundSymbolsNameModifier = methodList.get(1); assertDeepEquals(PUBLIC, resoleFoundSymbolsNameModifier.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), resoleFoundSymbolsNameModifier.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), resoleFoundSymbolsNameModifier.getMCReturnType().getMCType()); assertEquals(3, resoleFoundSymbolsNameModifier.sizeCDParameters()); assertBoolean(resoleFoundSymbolsNameModifier.getCDParameter(0).getMCType()); assertEquals("foundSymbols", resoleFoundSymbolsNameModifier.getCDParameter(0).getName()); @@ -441,7 +487,7 @@ public void testResolveManyAutomaton4ParamMethod() { ASTCDMethod method = methodList.get(0); assertDeepEquals(PUBLIC, method.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); assertEquals(4, method.sizeCDParameters()); assertBoolean(method.getCDParameter(0).getMCType()); assertEquals("foundSymbols", method.getCDParameter(0).getName()); @@ -460,7 +506,7 @@ public void testResolveAutomatonLocallyMethod() { ASTCDMethod method = getMethodBy("resolveAutomatonLocally", scopeInterface); assertDeepEquals(PUBLIC, method.getModifier()); - assertDeepEquals(MCTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); assertEquals(1, method.sizeCDParameters()); assertDeepEquals(String.class, method.getCDParameter(0).getMCType()); assertEquals("name", method.getCDParameter(0).getName()); @@ -473,7 +519,7 @@ public void testResolveAutomatonSubKindsMethod() { ASTCDMethod method = getMethodBy("resolveAutomatonSubKinds", scopeInterface); assertDeepEquals(PUBLIC_ABSTRACT, method.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); assertEquals(4, method.sizeCDParameters()); assertBoolean(method.getCDParameter(0).getMCType()); assertEquals("foundSymbols", method.getCDParameter(0).getName()); @@ -492,7 +538,7 @@ public void testResolveAutomatonLocallyManyMethod() { ASTCDMethod method = getMethodBy("resolveAutomatonLocallyMany", scopeInterface); assertDeepEquals(PUBLIC, method.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); assertEquals(4, method.sizeCDParameters()); assertBoolean(method.getCDParameter(0).getMCType()); assertEquals("foundSymbols", method.getCDParameter(0).getName()); @@ -511,7 +557,7 @@ public void testResolveAdaptedAutomatonLocallyManyMethod() { ASTCDMethod method = getMethodBy("resolveAdaptedAutomatonLocallyMany", scopeInterface); assertDeepEquals(PUBLIC, method.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); assertEquals(4, method.sizeCDParameters()); assertBoolean(method.getCDParameter(0).getMCType()); assertEquals("foundSymbols", method.getCDParameter(0).getName()); @@ -530,7 +576,7 @@ public void testContinueWithEnclosingScopeMethod() { ASTCDMethod method = getMethodBy("continueAutomatonWithEnclosingScope", scopeInterface); assertDeepEquals(PUBLIC, method.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); assertEquals(4, method.sizeCDParameters()); assertBoolean(method.getCDParameter(0).getMCType()); assertEquals("foundSymbols", method.getCDParameter(0).getName()); @@ -549,7 +595,7 @@ public void testContinueAsSubScopeMethod() { ASTCDMethod method = getMethodBy("continueAsAutomatonSubScope", scopeInterface); assertDeepEquals(PUBLIC, method.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); assertEquals(4, method.sizeCDParameters()); assertBoolean(method.getCDParameter(0).getMCType()); assertEquals("foundSymbols", method.getCDParameter(0).getName()); @@ -568,7 +614,7 @@ public void testFilterMethod() { ASTCDMethod method = getMethodBy("filterAutomaton", scopeInterface); assertDeepEquals(PUBLIC, method.getModifier()); - assertDeepEquals(MCTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createOptionalTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); assertEquals(2, method.sizeCDParameters()); assertDeepEquals(String.class, method.getCDParameter(0).getMCType()); assertEquals("name", method.getCDParameter(0).getName()); @@ -594,7 +640,7 @@ public void testGetLocalSymbolsMethod() { ASTCDMethod method = getMethodBy("getLocalAutomatonSymbols", scopeInterface); assertDeepEquals(PUBLIC, method.getModifier()); - assertDeepEquals(MCTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); + assertDeepEquals(mcTypeFacade.createListTypeOf(AUTOMATON_SYMBOL), method.getMCReturnType().getMCType()); assertTrue(method.isEmptyCDParameters()); assertTrue(Log.getFindings().isEmpty()); diff --git a/monticore-test/it/src/main/grammars/mc/feature/symboltable/SymbolsWithSubKinds.mc4 b/monticore-test/it/src/main/grammars/mc/feature/symboltable/SymbolsWithSubKinds.mc4 new file mode 100644 index 0000000000..09837c500c --- /dev/null +++ b/monticore-test/it/src/main/grammars/mc/feature/symboltable/SymbolsWithSubKinds.mc4 @@ -0,0 +1,37 @@ +/* (c) https://github.com/MontiCore/monticore */ + +package mc.feature.symboltable; + +grammar SymbolsWithSubKinds extends mc.common.Basics{ + + symbol scope Lot = + "lot" Name "{" (Vehicle)* "}" ; + + interface symbol Vehicle; + + interface Motorized; + + symbol scope Car implements Vehicle implements Motorized= + "car" Name; + + symbol scope Cabriolet extends Car = + "cabriolet" Name; + + symbol scope Beatle extends Cabriolet = + "beatle" Name; + + symbol scope Mazda extends Cabriolet = + "mazda" Name; + + symbol scope Truck extends Car = + "truck" Name; + + symbol scope Ford extends Truck = + "ford" Name; + + symbol scope Volvo extends Truck = + "volvo" Name; + + symbol scope Motorcycle implements Vehicle implements Motorized = + "motorcycle" Name; +} diff --git a/monticore-test/it/src/test/java/mc/feature/symboltable/SymbolsWithSubKindsTest.java b/monticore-test/it/src/test/java/mc/feature/symboltable/SymbolsWithSubKindsTest.java new file mode 100644 index 0000000000..dbc33c73ad --- /dev/null +++ b/monticore-test/it/src/test/java/mc/feature/symboltable/SymbolsWithSubKindsTest.java @@ -0,0 +1,119 @@ +/* (c) https://github.com/MontiCore/monticore */ + +package mc.feature.symboltable; + +import de.se_rwth.commons.logging.Log; +import de.se_rwth.commons.logging.LogStub; +import mc.GeneratorIntegrationsTest; +import mc.feature.symboltable.symbolswithsubkinds.SymbolsWithSubKindsMill; +import mc.feature.symboltable.symbolswithsubkinds._ast.*; +import mc.feature.symboltable.symbolswithsubkinds._parser.SymbolsWithSubKindsParser; +import mc.feature.symboltable.symbolswithsubkinds._symboltable.*; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Optional; + +public class SymbolsWithSubKindsTest extends GeneratorIntegrationsTest { + + @BeforeEach + public void before() { + LogStub.init(); + Log.enableFailQuick(false); + SymbolsWithSubKindsMill.reset(); + SymbolsWithSubKindsMill.init(); + } + + @Test + public void testSymbol() throws IOException { + // parse model + SymbolsWithSubKindsParser scopeAttributesParser = new SymbolsWithSubKindsParser(); + Optional astSup = scopeAttributesParser.parse("src/test/resources/mc/feature/symboltable/SymbolsWithSubKinds.st"); + Assertions.assertFalse(scopeAttributesParser.hasErrors()); + Assertions.assertTrue(astSup.isPresent()); + + // create symboltable + ISymbolsWithSubKindsGlobalScope globalScope = SymbolsWithSubKindsMill.globalScope(); + globalScope.setFileExt("st"); + globalScope.getSymbolPath().addEntry(Paths.get("src/test/resources/mc/feature/symboltable")); + + ISymbolsWithSubKindsScope scope = SymbolsWithSubKindsMill + .scopesGenitorDelegator().createFromAST(astSup.get()); + + Assertions.assertSame(1, scope.getSubScopes().size()); + ISymbolsWithSubKindsScope spannedScope = scope.getSubScopes().get(0); + Assertions.assertInstanceOf(SymbolsWithSubKindsScope.class , spannedScope); + + // check if the methods return the correct number of symbols + // see monticore-test/it/src/test/resources/mc/feature/symboltable/SymbolsWithSubKinds.st + Assertions.assertSame(1, spannedScope.getFordSymbolsWithSubKinds().size()); + Assertions.assertSame(1, spannedScope.getVolvoSymbolsWithSubKinds().size()); + Assertions.assertSame(3,spannedScope.getTruckSymbolsWithSubKinds().size()); + Assertions.assertSame(1,spannedScope.getBeatleSymbolsWithSubKinds().size()); + Assertions.assertSame(1, spannedScope.getMazdaSymbolsWithSubKinds().size()); + Assertions.assertSame(3,spannedScope.getCabrioletSymbolsWithSubKinds().size()); + Assertions.assertSame(7,spannedScope.getCarSymbolsWithSubKinds().size()); + Assertions.assertSame(1, spannedScope.getMotorcycleSymbolsWithSubKinds().size()); + Assertions.assertSame(8, spannedScope.getVehicleSymbolsWithSubKinds().size()); + + Assertions.assertEquals("carFordName", spannedScope.getFordSymbolsWithSubKinds().values().get(0).getName()); + Assertions.assertEquals("carVolvoName", spannedScope.getVolvoSymbolsWithSubKinds().values().get(0).getName()); + + Assertions.assertEquals("carFordName", spannedScope.getTruckSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(FordSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carVolvoName", spannedScope.getTruckSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(VolvoSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carTruckName", spannedScope.getTruckSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(TruckSymbol.class)).findAny().get().getName()); + + Assertions.assertEquals("carMazdaName", spannedScope.getMazdaSymbolsWithSubKinds().values().get(0).getName()); + Assertions.assertEquals("carBeatleName", spannedScope.getBeatleSymbolsWithSubKinds().values().get(0).getName()); + + Assertions.assertEquals("carMazdaName", spannedScope.getCabrioletSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(MazdaSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carBeatleName", spannedScope.getCabrioletSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(BeatleSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carCabrioletName", spannedScope.getCabrioletSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(CabrioletSymbol.class)).findAny().get().getName()); + + Assertions.assertEquals("carFordName", spannedScope.getCarSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(FordSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carVolvoName", spannedScope.getCarSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(VolvoSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carTruckName", spannedScope.getCarSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(TruckSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carMazdaName", spannedScope.getCarSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(MazdaSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carBeatleName", spannedScope.getCarSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(BeatleSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carCabrioletName", spannedScope.getCarSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(CabrioletSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carCarName", spannedScope.getCarSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(CarSymbol.class)).findAny().get().getName()); + + Assertions.assertEquals("motorcycleName", spannedScope.getMotorcycleSymbolsWithSubKinds().values().get(0).getName());; + + Assertions.assertEquals("carFordName", spannedScope.getVehicleSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(FordSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carVolvoName", spannedScope.getVehicleSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(VolvoSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carTruckName", spannedScope.getVehicleSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(TruckSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carMazdaName", spannedScope.getVehicleSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(MazdaSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carBeatleName", spannedScope.getVehicleSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(BeatleSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carCabrioletName", spannedScope.getVehicleSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(CabrioletSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("carCarName", spannedScope.getVehicleSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(CarSymbol.class)).findAny().get().getName()); + Assertions.assertEquals("motorcycleName", spannedScope.getVehicleSymbolsWithSubKinds().values().stream().filter(m -> m.getClass().equals(MotorcycleSymbol.class)).findAny().get().getName()); + + Assertions.assertTrue(Log.getFindings().isEmpty()); + } + + /** + * This test ensures that all expected classes are generated. Otherwise, the test will not compile + */ + @SuppressWarnings("unused") + @Test + public void test() { + ASTCar car = new ASTCarBuilder().uncheckedBuild(); + Assertions.assertInstanceOf(ASTVehicle.class, car); + ASTCabriolet cabriolet = new ASTCabrioletBuilder().uncheckedBuild(); + Assertions.assertInstanceOf(ASTCar.class, cabriolet); + ASTBeatle beatle = new ASTBeatleBuilder().uncheckedBuild(); + Assertions.assertInstanceOf(ASTCabriolet.class, beatle); + ASTMazda mazda = new ASTMazdaBuilder().uncheckedBuild(); + Assertions.assertInstanceOf(ASTCabriolet.class, mazda); + ASTTruck truck = new ASTTruckBuilder().uncheckedBuild(); + Assertions.assertInstanceOf(ASTCar.class, truck); + ASTFord ford = new ASTFordBuilder().uncheckedBuild(); + Assertions.assertInstanceOf(ASTTruck.class, ford); + ASTVolvo volvo = new ASTVolvoBuilder().uncheckedBuild(); + + Assertions.assertTrue(Log.getFindings().isEmpty()); + } +} diff --git a/monticore-test/it/src/test/resources/mc/feature/symboltable/SymbolsWithSubKinds.st b/monticore-test/it/src/test/resources/mc/feature/symboltable/SymbolsWithSubKinds.st new file mode 100644 index 0000000000..7dcff118fe --- /dev/null +++ b/monticore-test/it/src/test/resources/mc/feature/symboltable/SymbolsWithSubKinds.st @@ -0,0 +1,11 @@ +lot lotName { + ford carFordName + volvo carVolvoName + truck carTruckName + mazda carMazdaName + beatle carBeatleName + cabriolet carCabrioletName + car carCarName + motorcycle motorcycleName +} +