Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a2d1926
initial TypeCheck3
SE-FDr May 19, 2026
5960872
use TypeCheck3 in CDDiffUtil and TypeCheckMCTypeMatchingStrategy
Jun 24, 2026
b7c2005
refactor: Migrate ISynthesize to TypeCheck3; (constructor changes may…
0-ace-l0 Jun 29, 2026
4c92c13
Merge branch 'dev' into tc3
Jul 1, 2026
c4d296e
remove getDefiningSymbol()
0-ace-l0 Jul 8, 2026
a8fb0e2
replace isObjectType with isObscureType
Jul 8, 2026
c8638f4
CDNoImportResolverTest in cdlang
0-ace-l0 Jul 21, 2026
2b434f5
add MCArrayTypes to CD4A and CD4C TypeCheck3
Jul 22, 2026
dc8974c
CDNoImportResolverTest in cdlang
0-ace-l0 Jul 21, 2026
cdc6d5f
modify test and resolution down logic
Jul 22, 2026
0de3583
Merge remote-tracking branch 'origin/tc3-cdlang-tests' into tc3-cdlan…
0-ace-l0 Jul 28, 2026
b63fe88
modify test: p2.ClassA -> p2.p3.ClassA
0-ace-l0 Jul 30, 2026
40b9300
fix CDNoImportResolverTest
Jul 30, 2026
836ddfb
new Tests in CDSupertypeResolvingTest
0-ace-l0 Aug 6, 2026
406c567
override resolveTypeMany for CD4A and CD4C
Aug 6, 2026
8bf08bd
rebase tc3-cdlang-tests onto origin/dev: initial typecheck
SE-FDr May 19, 2026
65f0256
rebase tc3-cdlang-tests onto origin/dev: remove getDefiningSymbol()
0-ace-l0 Jul 8, 2026
1f12258
replace isObjectType with isObscureType
Jul 8, 2026
8d39640
CDNoImportResolverTest in cdlang
0-ace-l0 Jul 21, 2026
bbf2628
modify test and resolution down logic
Jul 22, 2026
1a3243c
modify test: p2.ClassA -> p2.p3.ClassA
0-ace-l0 Jul 30, 2026
ee3071b
rebase tc3-cdlang-tests onto origin/dev: fix CDNoImportResolverTest
Jul 30, 2026
e6db807
new Tests in CDSupertypeResolvingTest
0-ace-l0 Aug 6, 2026
81f1945
override resolveTypeMany for CD4A and CD4C
Aug 6, 2026
26dafb8
Merge remote-tracking branch 'origin/tc3-cdlang-tests' into tc3-cdlan…
0-ace-l0 Sep 23, 2026
d7f40b3
Rebase tc3-cdlang-tests to dev and integrate tc3 updates:
0-ace-l0 Sep 24, 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
7 changes: 4 additions & 3 deletions cdlang/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,10 @@ tasks.register('prepareEmptyTemplatesDir') {

tasks.withType(MCGenTask).configureEach {
// Use an empty templates directory (as we do not override any)
tmplDir = emptyTemplatesDir
dependsOn tasks.named('prepareEmptyTemplatesDir')
}
//tmplDir = emptyTemplatesDir
//dependsOn tasks.named('prepareEmptyTemplatesDir')
groovyHook2 = file "$projectDir/src/main/groovy/gh2sysml.groovy"
}

tasks.register('generateTestTrafos') {}
if (withDSTLGen) {
Expand Down
24 changes: 24 additions & 0 deletions cdlang/src/main/configTemplates/cdlang/ResolveMany4IScope.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<#-- (c) https://github.com/MontiCore/monticore -->
${tc.signature( "simpleName", "symbolFullName")}
// skip resolution of the symbol, if the symbol has already been resolved in this scope instance
// during the current execution of the resolution algorithm
if (is${simpleName}SymbolsAlreadyResolved()) {
return new de.monticore.symboltable.SetAsListAdapter<>();
}

// (1) resolve down per scope first for intra-scope resolution
final List<${symbolFullName}> resolvedSymbols = this.resolve${simpleName}DownMany(foundSymbols, name, modifier, predicate);
foundSymbols = foundSymbols | resolvedSymbols.size() > 0;

final String resolveCall = "resolveMany(\"" + name + "\", \"" + "${simpleName}Symbol"
+ "\") in scope \"" + (isPresentName() ? getName() : "") + "\"";
Log.trace("START " + resolveCall + ". Found #" + resolvedSymbols.size() + " (intra-model down)", "Resolving");

// (2) continue with enclosingScope, if either no symbol has been found yet or this scope is non-shadowing
final List<${symbolFullName}> resolvedFromEnclosing = continue${simpleName}WithEnclosingScope(foundSymbols, name, modifier, predicate);

// (3) unify results
resolvedSymbols.addAll(resolvedFromEnclosing);
Log.trace("END " + resolveCall + ". Found #" + resolvedSymbols.size(), "Resolving");

return resolvedSymbols;
49 changes: 49 additions & 0 deletions cdlang/src/main/groovy/gh2sysml.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import de.monticore.cd4codebasis._ast.ASTCDMethod
import de.monticore.cd4codebasis._ast.ASTCDMethodBuilder
import de.monticore.cd4codebasis._ast.ASTCDParameter
import de.monticore.cdbasis._ast.ASTCDClass
import de.monticore.cdbasis._ast.ASTCDCompilationUnit
import de.monticore.cdinterfaceandenum._ast.ASTCDInterface
import de.monticore.generating.templateengine.GlobalExtensionManagement
import de.monticore.generating.templateengine.StringHookPoint
import de.monticore.generating.templateengine.TemplateHookPoint
import de.monticore.types.mcbasictypes._ast.ASTMCQualifiedNameBuilder
import de.monticore.types.mcbasictypes._ast.ASTMCQualifiedTypeBuilder
import de.monticore.types.mccollectiontypes._ast.ASTMCBasicTypeArgument
import de.monticore.types.mccollectiontypes._ast.ASTMCBasicTypeArgumentBuilder
import de.monticore.types.mccollectiontypes._ast.ASTMCGenericType
import de.monticore.types.mccollectiontypes._ast.ASTMCListTypeBuilder
import de.monticore.types.mccollectiontypes._ast.ASTMCTypeArgument

/**
* This script replaces generated resolveMany methods to also look in related scopes
*/

// glex, astGrammar, decoratedCD
GlobalExtensionManagement glex = args[0] as GlobalExtensionManagement
ASTCDCompilationUnit decoratedCD = args[2] as ASTCDCompilationUnit

// TODO: Replace template is for some reason not transitive
// glex.replaceTemplate("_symboltable.iscope.Filter", new StringHookPoint(...))
// is never invoked, b/c TC#getTemplateForwardings only ever looks for one template
for (ASTCDInterface cl : decoratedCD.getCDDefinition().getCDInterfacesList()) {
if (cl.getName().endsWith("Scope") && !cl.getName().endsWith("ArtifactScope")) {
for (ASTCDMethod m : cl.getCDMethodList()) {
if (m.getMCReturnType().isPresentMCType() && m.getMCReturnType().getMCType() instanceof ASTMCGenericType) {
ASTMCTypeArgument symbolType = ((ASTMCGenericType) m.getMCReturnType().getMCType()).getMCTypeArgumentList().get(0);
List<String> nameList = ((ASTMCBasicTypeArgument) symbolType).getMCQualifiedType().getNameList();
String last = nameList.get(nameList.size() - 1);
String actualName = last.substring(0, last.length() - 6);

String potResolveDownMethodName = "resolve" + actualName + "Many"

if (m.getName().equals(potResolveDownMethodName) && m.getCDParameterList().size() == 4 && !cl.getName().endsWith("GlobalScope")) {
//System.out.println("replacing " + potResolveDownMethodName)

glex.replaceTemplate("cd2java.EmptyBody", m, new TemplateHookPoint("cdlang.ResolveMany4IScope",
actualName, symbolType.printType()))
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* (c) https://github.com/MontiCore/monticore */
package de.monticore.cd4analysis._symboltable;

import de.monticore.symbols.basicsymbols._symboltable.TypeSymbol;
import de.se_rwth.commons.logging.Log;

import java.util.List;

public interface ICD4AnalysisScope extends ICD4AnalysisScopeTOP {

@Override
default public List<TypeSymbol> resolveTypeMany(boolean foundSymbols, String name,
de.monticore.symboltable.modifiers.AccessModifier modifier,
java.util.function.Predicate<de.monticore.symbols.basicsymbols._symboltable.TypeSymbol> predicate) {
/* generated by template _symboltable.iscope.ResolveMany4IScope*/

// skip resolution of the symbol, if the symbol has already been resolved in this scope instance
// during the current execution of the resolution algorithm
if (isTypeSymbolsAlreadyResolved()) {
return new de.monticore.symboltable.SetAsListAdapter<>();
}

// (1) resolve symbol locally. During this, the 'already resolved' flag is set to true,
// to prevent resolving cycles caused by cyclic symbol adapters
//setTypeSymbolsAlreadyResolved(true);
final List<de.monticore.symbols.basicsymbols._symboltable.TypeSymbol> resolvedSymbols = this
.resolveTypeDownMany(foundSymbols, name, modifier, predicate);
foundSymbols = foundSymbols | resolvedSymbols.size() > 0;
//setTypeSymbolsAlreadyResolved(false);

final String resolveCall = "resolveMany(\"" + name + "\", \"" + "TypeSymbol" + "\") in scope \""
+ (isPresentName() ? getName() : "") + "\"";
Log.trace("START " + resolveCall + ". Found #" + resolvedSymbols.size() + " (local)",
"Resolving");

// (2) continue with enclosingScope, if either no symbol has been found yet or this scope is non-shadowing
final List<de.monticore.symbols.basicsymbols._symboltable.TypeSymbol> resolvedFromEnclosing =
continueTypeWithEnclosingScope(foundSymbols, name, modifier, predicate);

// (3) unify results
resolvedSymbols.addAll(resolvedFromEnclosing);
Log.trace("END " + resolveCall + ". Found #" + resolvedSymbols.size(), "Resolving");

return resolvedSymbols;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* (c) https://github.com/MontiCore/monticore */
package de.monticore.cd4code._symboltable;

import de.monticore.symbols.basicsymbols._symboltable.TypeSymbol;
import de.se_rwth.commons.logging.Log;

import java.util.List;

public interface ICD4CodeScope extends ICD4CodeScopeTOP {

@Override
default public List<TypeSymbol> resolveTypeMany(boolean foundSymbols, String name,
de.monticore.symboltable.modifiers.AccessModifier modifier,
java.util.function.Predicate<de.monticore.symbols.basicsymbols._symboltable.TypeSymbol> predicate) {
/* generated by template _symboltable.iscope.ResolveMany4IScope*/

// skip resolution of the symbol, if the symbol has already been resolved in this scope instance
// during the current execution of the resolution algorithm
if (isTypeSymbolsAlreadyResolved()) {
return new de.monticore.symboltable.SetAsListAdapter<>();
}

// (1) resolve symbol locally. During this, the 'already resolved' flag is set to true,
// to prevent resolving cycles caused by cyclic symbol adapters
//setTypeSymbolsAlreadyResolved(true);
final List<de.monticore.symbols.basicsymbols._symboltable.TypeSymbol> resolvedSymbols = this
.resolveTypeDownMany(foundSymbols, name, modifier, predicate);
foundSymbols = foundSymbols | resolvedSymbols.size() > 0;
//setTypeSymbolsAlreadyResolved(false);

final String resolveCall = "resolveMany(\"" + name + "\", \"" + "TypeSymbol" + "\") in scope \""
+ (isPresentName() ? getName() : "") + "\"";
Log.trace("START " + resolveCall + ". Found #" + resolvedSymbols.size() + " (local)",
"Resolving");

// (2) continue with enclosingScope, if either no symbol has been found yet or this scope is non-shadowing
final List<de.monticore.symbols.basicsymbols._symboltable.TypeSymbol> resolvedFromEnclosing =
continueTypeWithEnclosingScope(foundSymbols, name, modifier, predicate);

// (3) unify results
resolvedSymbols.addAll(resolvedFromEnclosing);
Log.trace("END " + resolveCall + ". Found #" + resolvedSymbols.size(), "Resolving");

return resolvedSymbols;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,15 @@ protected void initialize_CDClass(ASTCDClass ast) {

@Override
public void visit(ASTCDAttribute node) {
// ======= merge test =======
if (node.getName().equals("worker")) {
System.out.println(" CDBasisCompleter visits 'worker'");
var res = TypeCheck3.symTypeFromAST(node.getMCType());
System.out.println("calculated type: " + (res == null ? "null" : res.print())
+ " (is obscure? " + (res != null && res.isObscureType()) + ")");
}
// =====================================

final FieldSymbol symbol = node.getSymbol();

// Compute the !final! SymTypeExpression for the type of the field
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/* (c) https://github.com/MontiCore/monticore */
package de.monticore.cd4code.resolver;

import de.monticore.cd4code.CD4CodeMill;
import de.monticore.cd4code.CD4CodeTestBasis;
import de.monticore.cd4code._symboltable.CD4CodeSymbolTableCompleter;
import de.monticore.cdbasis._ast.ASTCDCompilationUnit;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeAll;

import java.io.IOException;
import java.util.Optional;

import static org.junit.Assert.assertTrue;

public class CDNoImportResolverTest extends CD4CodeTestBasis {

String ModelA = """
classdiagram CD2 {
package p2 {
package p3 {
class ClassA {
public int value;
}
}
class ClassC {
public p2.p3.ClassA value;
}
}
}
""";

String ModelB = """
classdiagram CD1 {
package p1 {
class ClassB {
private p2.p3.ClassA myAttribute;
}
}
}
""";
//With Import
String ModelBImport = """
package p1;
import p2.p3.ClassA;

classdiagram CD1 {
class ClassB {
private ClassA myAttribute;
}
}
""";

@BeforeAll
public static void init() throws Exception {
CD4CodeMill.reset();
CD4CodeMill.init();

}

@Test
public void resolvingWithoutImport() throws IOException {
//parse Models
final Optional<ASTCDCompilationUnit> optA = CD4CodeMill.parser().parse_String(ModelA);
assertTrue(optA.isPresent());
ASTCDCompilationUnit astA = optA.get();

Optional<ASTCDCompilationUnit> optB = CD4CodeMill.parser().parse_String(ModelB);
assertTrue(optB.isPresent());
ASTCDCompilationUnit astB = optB.get();

//initalize the Scopes
CD4CodeMill.scopesGenitorDelegator().createFromAST(astA);
CD4CodeMill.scopesGenitorDelegator().createFromAST(astB);

CD4CodeSymbolTableCompleter completerB = new CD4CodeSymbolTableCompleter(astA);
astA.accept(completerB.getTraverser());

CD4CodeSymbolTableCompleter completerA = new CD4CodeSymbolTableCompleter(astB);
astB.accept(completerA.getTraverser());

var resolved = astB.getEnclosingScope().resolveCDType("p2.p3.ClassA");

assertTrue("ClassA could not be found!", resolved.isPresent());

var siblingSymbol = astA.getEnclosingScope().resolveCDType("p2.ClassC");
assertTrue(siblingSymbol.isPresent());

var res2 = siblingSymbol.get().getSpannedScope().resolveCDType("p3.ClassA");
assertTrue(res2.isPresent());
}

@Test
public void resolvingWithImport() throws IOException {
//parse Models
final Optional<ASTCDCompilationUnit> optA = CD4CodeMill.parser().parse_String(ModelA);
assertTrue(optA.isPresent());
ASTCDCompilationUnit astA = optA.get();

Optional<ASTCDCompilationUnit> optB = CD4CodeMill.parser().parse_String(ModelBImport);
assertTrue(optB.isPresent());
ASTCDCompilationUnit astB = optB.get();

//initalize the Scopes
CD4CodeMill.scopesGenitorDelegator().createFromAST(astA);
CD4CodeMill.scopesGenitorDelegator().createFromAST(astB);

CD4CodeSymbolTableCompleter completerB = new CD4CodeSymbolTableCompleter(astA);
astA.accept(completerB.getTraverser());

CD4CodeSymbolTableCompleter completerA = new CD4CodeSymbolTableCompleter(astB);
astB.accept(completerA.getTraverser());

var resolved = astB.getEnclosingScope().resolveCDType("p2.p3.ClassA");

assertTrue("ClassA could not be found!", resolved.isPresent());
}

}
Loading
Loading