Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0706e43
build method signature
Hendrik7889 Aug 23, 2025
744f432
initial steps
Hendrik7889 Aug 25, 2025
a423603
Fix test grammar.
N-Jansen Aug 26, 2025
902f91f
finished signature and raw structure
Hendrik7889 Aug 29, 2025
5ceaf09
sync
Hendrik7889 Sep 1, 2025
219f44b
adjust tests for ScopeInterfaceDecorator and ScopeClassDecorator
Hendrik7889 Sep 1, 2025
c1017f6
added logic for subkind discovery
Hendrik7889 Sep 2, 2025
9102f5f
sync
Hendrik7889 Sep 10, 2025
6f5da6e
finished up test
Hendrik7889 Sep 11, 2025
9dd4cc9
cleanup
Hendrik7889 Sep 11, 2025
0989252
small fix
Hendrik7889 Sep 11, 2025
aa93a5b
Merge branch 'dev' into scope-utilities
Hendrik7889 Sep 13, 2025
5692219
getSymbol error
Hendrik7889 Sep 15, 2025
8885ba3
untested changes interface symbols test untested and just a copy yet
Hendrik7889 Sep 22, 2025
fddca11
remove diamond structure in tests
Hendrik7889 Oct 7, 2025
68d46c5
Merge branch 'dev' into scope-utilities
Hendrik7889 Oct 13, 2025
23ed783
Merge branch 'dev' into scope-utilities
SE-FDr Nov 28, 2025
67c87de
Merge branch 'dev' into scope-utilities
Hendrik7889 Jan 19, 2026
5c9cb2e
migrate tests to JUnit5
Hendrik7889 Jan 19, 2026
b7cb09e
Merge branch 'dev' into scope-utilities
Hendrik7889 Jan 22, 2026
ebe184b
Merge branch 'dev' into scope-utilities
Hendrik7889 Jan 28, 2026
2ebc5f6
Merge branch 'dev' into scope-utilities
Hendrik7889 Feb 16, 2026
3199781
Merge branch 'dev' into scope-utilities
Hendrik7889 Feb 21, 2026
298c40e
Merge branch 'dev' into scope-utilities
Hendrik7889 Feb 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -123,7 +121,7 @@ public ASTCDClass decorate(ASTCDCompilationUnit scopeInput, ASTCDCompilationUnit
symbolInput.getCDDefinition().getCDClassesList(), symbolTableService.getCDSymbol());
symbolAttributes.putAll(getSuperSymbolAttributes());

List<ASTCDMethod> symbolMethods = createSymbolMethods(symbolAttributes.values());
List<ASTCDMethod> symbolMethods = createSymbolMethods(symbolAttributes.values(), symbolInput.getCDDefinition());

List<ASTCDAttribute> symbolAlreadyResolvedAttributes = createSymbolAlreadyResolvedAttributes(
symbolAttributes.keySet());
Expand Down Expand Up @@ -300,7 +298,7 @@ protected Map<String, ASTCDAttribute> 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<ASTCDAttribute> createSymbolAttribute(ASTCDType cdType,
DiagramSymbol cdDefinitionSymbol) {
Expand Down Expand Up @@ -334,7 +332,7 @@ protected List<ASTCDAttribute> createSymbolAlreadyResolvedAttributes(
return symbolAttributeList;
}

protected List<ASTCDMethod> createSymbolMethods(Collection<ASTCDAttribute> astcdAttributes) {
protected List<ASTCDMethod> createSymbolMethods(Collection<ASTCDAttribute> astcdAttributes, ASTCDDefinition symbolInput) {
List<ASTCDMethod> symbolMethodList = new ArrayList<>();
for (ASTCDAttribute attribute : astcdAttributes) {
if (attribute.getMCType() instanceof ASTMCBasicGenericType
Expand All @@ -345,6 +343,7 @@ protected List<ASTCDMethod> createSymbolMethods(Collection<ASTCDAttribute> astcd
symbolMethodList.add(createAddSymbolMethod(mcTypeArgument.get(), attribute.getName()));
symbolMethodList.add(createRemoveSymbolMethod(mcTypeArgument.get(), attribute.getName()));
symbolMethodList.add(createGetSymbolListMethod(attribute));
symbolMethodList.add(createGetSymbolsWithSubKindsMethod(attribute, symbolInput));
}
}
}
Expand Down Expand Up @@ -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<String> result = new HashSet<>();
List<ASTCDType> symbols = symbolTableService.getSymbolDefiningProds(symbolDefinition);
symbols.addAll(symbolTableService.getSymbolDefiningSuperProds());
ListMultimap<String, String> subKinds = SymbolKindHierarchies
.calculateSubKinds(symbols, symbolTableService);

//get names of attribute and check the subkindsMap for them recursively
List<String> lastAttributeNames = new ArrayList<>();
//as all attribute come in the Form <kind>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<String> 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(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -259,6 +258,10 @@ protected List<ASTCDMethod> createScopeInterfaceMethodsForSymbols(List<? extends
String getSymbolsMethodName = "get" + className + "Symbols";
resolveMethods.add(createGetSymbolsMethod(getSymbolsMethodName, symbolFullTypeName));

//getSymbolsWithSubKinds method
String getSymbolsWithSubKindsMethodName = "get" + className + "SymbolsWithSubKinds";
resolveMethods.add(createGetSymbolsWithSubKindsMethod(getSymbolsWithSubKindsMethodName, symbolFullTypeName, symbolProd.getSymbol()));

//getLocalSymbols method
String getLocalSymbolsMethodName = "getLocal" + className + "Symbols";
resolveMethods.add(createGetLocalSymbolsMethod(getLocalSymbolsMethodName, className, getMCTypeFacade().createListTypeOf(symbolFullTypeName)));
Expand Down Expand Up @@ -516,6 +519,12 @@ protected ASTCDMethod createGetSymbolsMethod(String methodName, String fullSymbo
return getCDMethodFacade().createMethod(PUBLIC_ABSTRACT.build(), symbolsMap, methodName);
}

protected ASTCDMethod createGetSymbolsWithSubKindsMethod(String methodName, String fullSymbolName, CDTypeSymbol type) {
ASTMCType symbolsMap = getMCTypeFacade().createBasicGenericTypeOf(SYMBOL_MULTI_MAP, "String", fullSymbolName);

return getCDMethodFacade().createMethod(PUBLIC_ABSTRACT.build(), symbolsMap, methodName);
}

protected ASTCDMethod createGetLocalSymbolsMethod(String methodName, String className, ASTMCType returnType) {
ASTCDMethod method = getCDMethodFacade().createMethod(PUBLIC.build(), returnType, methodName);
this.replaceTemplate(EMPTY_BODY, method, new StringHookPoint("return get" + className + "Symbols().values();"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<#-- (c) https://github.com/MontiCore/monticore -->
${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());
</#list>
return symbols;
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ public static List<ASTCDMethod> getMethodsBy(String name, int parameterSize, Lis
m -> parameterSize == m.getCDParameterList().size()));
}

public static List<ASTCDMethod> getMethodsBy(List<ASTCDMethod> methods, List<Predicate<ASTCDMethod>> predicates) {
return filterMethods(methods, predicates);
}

public static ASTCDMethod getMethodBy(List<ASTCDMethod> methods, List<Predicate<ASTCDMethod>> predicates) {
return filterMethodsOrFail(methods, predicates);
}

public static ASTCDMethod getMethodBy(String name, List<ASTCDMethod> methods) {
return filterMethodsOrFail(methods, Collections.singletonList(
m -> name.equals(m.getName())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -60,6 +59,8 @@ public class ScopeClassDecoratorTest extends DecoratorTestCase {

private static final String QUALIFIED_NAME_SYMBOL_MAP = "com.google.common.collect.LinkedListMultimap<String,de.monticore.codegen.ast.lexicals._symboltable.QualifiedNameSymbol>";

private static final String UNKNOWN_SYMBOL_MAP = "com.google.common.collect.LinkedListMultimap<String,de.monticore.symboltable.SymbolWithScopeOfUnknownKind>";

private static final String FOO_SYMBOL_MAP = "com.google.common.collect.LinkedListMultimap<String,de.monticore.codegen.symboltable.automaton._symboltable.FooSymbol>";

private static final String AUTOMATON_SYMBOL = "de.monticore.codegen.symboltable.automaton._symboltable.AutomatonSymbol";
Expand All @@ -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");
Expand Down Expand Up @@ -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());
}
Expand Down Expand Up @@ -467,8 +467,6 @@ public void testAddSymbolMethod() {
assertTrue(Log.getFindings().isEmpty());
}



@Test
public void testGetAutomatonSymbolsMethod() {
ASTCDMethod method = getMethodBy("getAutomatonSymbols", scopeClass);
Expand All @@ -481,6 +479,46 @@ public void testGetAutomatonSymbolsMethod() {
assertTrue(Log.getFindings().isEmpty());
}

@Test
public void testGetSymbolWithSubKindsMethod() {
List<Predicate<ASTCDMethod>> predicates = Arrays.asList(
m -> m.getName().endsWith("WithSubKinds")
);
List<ASTCDMethod> methodList = getMethodsBy(scopeClass.getCDMethodList(), predicates);
Map<String, ASTCDMethod> 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() {
Expand Down
Loading
Loading