Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion cdlang/src/main/java/de/monticore/CDGeneratorTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
* This class is scheduled for removal/replacement by the decorating {@link
* de.monticore.cdgen.CDGenTool}
*/
@Deprecated
@Deprecated(forRemoval = true)
public class CDGeneratorTool extends CD4CodeTool {

/**
Expand Down
145 changes: 133 additions & 12 deletions cdlang/src/main/java/de/monticore/cdgen/CDGenTool.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* (c) https://github.com/MontiCore/monticore */
package de.monticore.cdgen;

import de.monticore.CDGeneratorTool;
import de.monticore.cd.codegen.CDGenService;
import de.monticore.cd.codegen.CDGenerator;
import de.monticore.cd.codegen.CdUtilsPrinter;
Expand All @@ -13,43 +12,52 @@
import de.monticore.cd4analysis.trafo.CDAssociationCreateFieldsFromAllRoles;
import de.monticore.cd4analysis.trafo.CDAssociationCreateFieldsFromNavigableRoles;
import de.monticore.cd4code.CD4CodeMill;
import de.monticore.cd4code.CD4CodeTool;
import de.monticore.cd4code._cocos.CD4CodeCoCoChecker;
import de.monticore.cd4code._symboltable.CD4CodeScopesGenitorDelegatorTOP;
import de.monticore.cd4code._symboltable.CD4CodeSymbolTableCompleter;
import de.monticore.cd4code._symboltable.ICD4CodeArtifactScope;
import de.monticore.cd4code._visitor.CD4CodeTraverser;
import de.monticore.cd4code.cocos.CD4CodeCoCosDelegator;
import de.monticore.cd4code.trafo.CD4CodeAfterParseTrafo;
import de.monticore.cdbasis.CDBasisMill;
import de.monticore.cdbasis._ast.ASTCDClass;
import de.monticore.cdbasis._ast.ASTCDCompilationUnit;
import de.monticore.cdbasis.trafo.CDBasisDefaultPackageTrafo;
import de.monticore.cdinterfaceandenum._ast.ASTCDEnum;
import de.monticore.cdinterfaceandenum._ast.ASTCDInterface;
import de.monticore.class2mc.OOClass2MCResolver;
import de.monticore.generating.GeneratorSetup;
import de.monticore.generating.templateengine.GlobalExtensionManagement;
import de.monticore.generating.templateengine.TemplateController;
import de.monticore.generating.templateengine.TemplateHookPoint;
import de.monticore.generating.templateengine.*;
import de.monticore.io.paths.MCPath;
import de.monticore.symbols.basicsymbols.BasicSymbolsMill;
import de.monticore.symboltable.ImportStatement;
import de.monticore.types.MCTypeFacade;
import de.monticore.types.mcbasictypes._ast.ASTMCImportStatement;
import de.monticore.types.mccollectiontypes.types3.MCCollectionSymTypeRelations;
import de.se_rwth.commons.Names;
import de.se_rwth.commons.logging.Log;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.cli.*;

/**
* This class is a further development of the {@link CDGeneratorTool} and meant as a replacement. It
* provides configurable decorator functionality in addition to generation. This tool is tested via
* This tool provides configurable decorator functionality in addition to generation. This tool is
* tested via
* the CDGenGradlePluginTest:
* cdtool/cdgradle/src/test/java/de/monticore/cdgen/CDGenGradlePluginTest.java
*/
public class CDGenTool extends CDGeneratorTool {
public class CDGenTool extends CD4CodeTool {

/**
* Gradle main method of the CDGenTool
Expand All @@ -68,8 +76,18 @@ public static void gradleMain(String[] args) {
*/
public static void main(String[] args) {
Log.init();
CDGenTool tool = new CDGenTool();
tool.run(args);
try {
CD4CodeTool tool = new CDGenTool();
tool.run(args);
}
catch (Exception exception) {
// ensure a sane exit
Log.error("0xEEEEE an internal error occurred" + " during the execution of the CD4CodeTool."
+ System.lineSeparator() + "This error is unexpected"
+ " and does not indicate an issue with any provided models.", exception);
}
// properly exit with a code
System.exit(Log.getErrorCount() == 0 ? 0 : 1);
}

/**
Expand Down Expand Up @@ -207,6 +225,11 @@ public void initializeSymbolTable(boolean c2mc) {
}
}

public void initializeClass2MC() {
CD4CodeMill.globalScope().addAdaptedTypeSymbolResolver(new OOClass2MCResolver());
CD4CodeMill.globalScope().addAdaptedOOTypeSymbolResolver(new OOClass2MCResolver());
}

public void initializeDecConf(GlobalExtensionManagement glex, DecoratorConfig decConfig,
CommandLine cmd, GeneratorSetup setup) {
// Setup CLI config overrides
Expand Down Expand Up @@ -397,12 +420,13 @@ public void runBeforeSTCoCos(ASTCDCompilationUnit ast) {
* @param ast the original ast
*/
public void runCoCos(ASTCDCompilationUnit ast) {
super.runCoCos(ast);
CD4CodeCoCoChecker checker = new CD4CodeCoCosDelegator().getCheckerForAllCoCos();
checker.checkAll(ast);
}

@Override
public Collection<ASTCDCompilationUnit> trafoBeforeSymtab(Collection<ASTCDCompilationUnit> asts) {
super.trafoBeforeSymtab(asts);
CD4CodeAfterParseTrafo trafo = new CD4CodeAfterParseTrafo();
asts.forEach(ast -> ast.accept(trafo.getTraverser()));
// TODO: Have this be done via the config-options (#4310)
var t = CD4CodeMill.inheritanceTraverser();
t.add4UMLModifier(new DefaultVisibilityPublicTrafo());
Expand Down Expand Up @@ -440,4 +464,101 @@ public void mapCD4CImports(ASTCDCompilationUnit ast) {
}
}

public MCPath createModelPath(CommandLine cl) {
if (cl.hasOption("i")) {
return new MCPath(splitPathEntries(cl.getOptionValues("i")));
}
else {
return new MCPath();
}
}

public String[] splitPathEntries(String composedPath) {
Objects.requireNonNull(composedPath);

return composedPath.split(Pattern.quote(File.pathSeparator));
}

public final String[] splitPathEntries(String[] composedPaths) {
Objects.requireNonNull(composedPaths);
return Arrays.stream(composedPaths).map(this::splitPathEntries).flatMap(Arrays::stream).toArray(
String[]::new);
}

public Collection<ASTCDCompilationUnit> parse(String fileExt, Collection<Path> filesAndDirs) {
return filesAndDirs.stream().flatMap(dirOrFile -> this.parse(fileExt, dirOrFile).stream())
.collect(Collectors.toList());
}

/**
* Parses all class diagrams in the given path.
* In case the path is a file, the file is parsed regardless of its extension
* Otherwise, all files within the path-directory are parsed if their extension matches
*
* @param fileExt recursively parses all files with this extension in a directory
* @param fileOrDir directory or file
* @return a collection of nested files
*/
public Collection<ASTCDCompilationUnit> parse(String fileExt, Path fileOrDir) {
if (Files.isRegularFile(fileOrDir)) {
// In case a file is within the ModelPath: parse the file
return Collections.singleton(this.parse(fileOrDir.toString()));
}
// Otherwise: Traverse the directory & parse all matching files
try (
Stream<Path> paths = Files.walk(fileOrDir)
) {
return paths.filter(Files::isRegularFile).filter(file -> file.getFileName().toString()
.endsWith(fileExt)).map(Path::toString).map(this::parse).collect(Collectors.toSet());
}
catch (IOException e) {
Log.error("0xA1063 Error while traversing the file structure `" + fileOrDir + "`.", e);
}
return Collections.emptySet();
}

/**
* creates the symboltable for the given ast
*
* @param ast the input ast
* @param java whether to add java default imports
* @return the symbol-table of the ast
*/
public ICD4CodeArtifactScope createSymbolTable(ASTCDCompilationUnit ast, boolean java) {
CD4CodeScopesGenitorDelegatorTOP genitor = CD4CodeMill.scopesGenitorDelegator();
ICD4CodeArtifactScope scope = genitor.createFromAST(ast);
this.addDefaultImports(scope, java);
return scope;
}

public void addDefaultImports(ICD4CodeArtifactScope scope, boolean java) {
if (java)
scope.addImports(new ImportStatement("java.lang", true));
}

/**
* prints the symboltable of the given scope out to a file
*
* @param scope symboltable to store
* @param path location of the file or directory containing the printed table
*/
public void storeSymTab(ICD4CodeArtifactScope scope, String path) {
if (Path.of(path).toFile().isFile()) {
this.storeSymbols(scope, path);
}
else {
this.storeSymbols(scope, Paths.get(path, Names.getPathFromPackage(scope.getFullName())
+ ".cdsym").toString());
}
}

/**
* completes the symboltable for the given ast
*
* @param ast the input ast
*/
public void completeSymbolTable(ASTCDCompilationUnit ast) {
ast.accept(new CD4CodeSymbolTableCompleter(ast).getTraverser());
}

}
44 changes: 23 additions & 21 deletions cdlang/src/test/java/de/monticore/CDGeneratorToolTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import de.monticore.cd4code.CD4CodeMill;
import de.monticore.cd4code._symboltable.CD4CodeSymbols2Json;
import de.monticore.cd4code._symboltable.ICD4CodeArtifactScope;
import de.monticore.cdgen.CDGenTool;
import de.monticore.runtime.junit.MCAssertions;
import de.monticore.symbols.basicsymbols.BasicSymbolsMill;
import de.se_rwth.commons.logging.LogStub;
import java.io.File;
Expand All @@ -16,6 +18,7 @@
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

public class CDGeneratorToolTest {
Expand All @@ -30,30 +33,29 @@ public void before() {

@Test
public void testGeneratorToolWithCoCos() {
CDGeneratorTool.main(new String[] { "-i",
new CDGenTool().run(new String[] { "-i",
"src/test/resources/de/monticore/cdgentool/model/Example.cd", "-c2mc", "-c" });
assertTrue(true);
}

@Test
public void testGeneratorToolWithSymbolTable() {
CDGeneratorTool.main(new String[] { "-i",
new CDGenTool().run(new String[] { "-i",
"src/test/resources/de/monticore/cdgentool/model/Example.cd", "-c2mc", "-s",
"target/generated/example/symboltable" });
assertTrue(new File("target/generated/example/symboltable/model/Example.cdsym").isFile());
}

@Test
public void testGeneratorToolWithJavaGeneration() {
CDGeneratorTool.main(new String[] { "-i",
new CDGenTool().run(new String[] { "-i",
"src/test/resources/de/monticore/cdgentool/model/Example.cd", "-c2mc", "-o",
"target/generated/example/standard", });
assertTrue(new File("target/generated/example/standard/model/Example/A.java").isFile());
}

@Test
public void testGeneratorToolWithEmptyCDWithPackage() {
CDGeneratorTool.main(new String[] { "-i",
new CDGenTool().run(new String[] { "-i",
"src/test/resources/de/monticore/cdgentool/model/EmptyWithPackage.cd", "-c2mc", "-o",
"target/generated/example/standard", });

Expand All @@ -63,23 +65,25 @@ public void testGeneratorToolWithEmptyCDWithPackage() {
@Test
public void testGeneratorToolWithEmptyCDWithoutPackage() {

CDGeneratorTool.main(new String[] { "-i",
new CDGenTool().run(new String[] { "-i",
"src/test/resources/de/monticore/cdgentool/model/EmptyWithoutPackage.cd", "-c2mc", "-o",
"target/generated/example/standard", });
assertTrue(new File("target/generated/example/standard/EmptyWithoutPackage").isDirectory());
}

@Test
@Disabled // The new generator has a different configTemplate opinion
public void testGeneratorToolWithCustomGeneratorTemplate() {
CDGeneratorTool.main(new String[] { "-i",
new CDGenTool().run(new String[] { "-i",
"src/test/resources/de/monticore/cdgentool/model/Example.cd", "-c2mc", "-o",
"target/generated/example/ct", "-ct", "de.monticore.cdgentool.NewCustomTemplate" });
assertTrue(new File("target/generated/example/ct/model/Example/A.java").isFile());
}

@Test
@Disabled // New generator has a different CLI options
public void testGeneratorToolWithAdditionalTemplates() {
CDGeneratorTool.main(new String[] { "-i",
new CDGenTool().run(new String[] { "-i",
"src/test/resources/de/monticore/cdgentool/model/Example.cd", "-c2mc", "-o",
"target/generated/example/tp", "-tp",
"src/test/resources/de/monticore/cdgentool/templates" });
Expand All @@ -88,28 +92,26 @@ public void testGeneratorToolWithAdditionalTemplates() {

@Test
public void testGeneratorToolWithHWC() {
CDGeneratorTool.main(new String[] { "-i",
new CDGenTool().run(new String[] { "-i",
"src/test/resources/de/monticore/cdgentool/model/Example.cd", "-c2mc", "-o",
"target/generated/example/hwc", "-hwc", "src/test/resources/de/monticore/cdgentool/hwc" });
assertTrue(new File("target/generated/example/hwc/model/Example/ATOP.java").isFile());
}

@Test
public void testToolPrintHelpOptions() {
CDGeneratorTool.main(new String[] { "-h" });
assertTrue(true);
new CDGenTool().run(new String[] { "-h" });
}

@Test
public void testToolPrintVersion() {
CDGeneratorTool.main(new String[] { "-i",
new CDGenTool().run(new String[] { "-i",
"src/test/resources/de/monticore/cdgentool/model/Example.cd", "-c2mc", "-v" });
assertTrue(true);
}

@Test
public void testGeneratorToolWithPkgSymTab() throws IOException {
CDGeneratorTool.main(new String[] { "-i",
new CDGenTool().run(new String[] { "-i",
"src/test/resources/de/monticore/cdgentool/pkg/ExampleWithPkg.cd", "-c2mc", "-o",
"target/generated/example/examplewithpkg", "-s",
"target/generated/example/examplewithpkg" });
Expand All @@ -120,8 +122,9 @@ public void testGeneratorToolWithPkgSymTab() throws IOException {
}

@Test
@Disabled // The new generated uses a different set of decorators
public void testDefaultConstructorDecorator() {
CDGeneratorTool.main(new String[] { "-i",
new CDGenTool().run(new String[] { "-i",
"src/test/resources/de/monticore/cdgentool/model/Example.cd", "-c2mc", "-o",
"target/generated/example/defaultctor", "-ct",
"de.monticore.cdgentool.DefaultCtorTemplate", });
Expand All @@ -131,21 +134,20 @@ public void testDefaultConstructorDecorator() {

@Test
public void testImportStatements() {
CDGeneratorTool.main(new String[] { "-i",
new CDGenTool().run(new String[] { "-i",
"src/test/resources/de/monticore/cdgentool/model/Example.cd", "-o",
"target/generated/example/imports", "-c2mc", "-s", "target/generated/example/imports/" });

CDGeneratorTool.main(new String[] { "-i",
new CDGenTool().run(new String[] { "-i",
"src/test/resources/de/monticore/cdgentool/ImportTest.cd", "-o",
"target/generated/example/imports", "-c2mc", "-path",
"target/generated/example/imports/" });

assertTrue(true);
}

@Test
@Disabled // The new generator does not have a "fieldfromrole" option
public void testAttributesForAssociations() {
CDGeneratorTool.main(new String[] { "-i",
new CDGenTool().run(new String[] { "-i",
"src/test/resources/de/monticore/cdgentool/model/Example.cd", "-c2mc", "-s",
"target/generated/example/rolefield/", "-fieldfromrole", "navigable" });
File symtab = new File("target/generated/example/rolefield/model/Example.cdsym");
Expand All @@ -159,8 +161,8 @@ public void testAttributesForAssociations() {

@AfterEach
public void after() {
MCAssertions.assertNoFindings();
CD4CodeMill.globalScope().clear();
assertTrue(LogStub.getFindings().isEmpty());
}

}
Loading