diff --git a/cdlang/src/main/java/de/monticore/cd/cocos/ImplementOnlyInterfaces.java b/cdlang/src/main/java/de/monticore/cd/cocos/ImplementOnlyInterfaces.java index 21cb17afe..91371d521 100644 --- a/cdlang/src/main/java/de/monticore/cd/cocos/ImplementOnlyInterfaces.java +++ b/cdlang/src/main/java/de/monticore/cd/cocos/ImplementOnlyInterfaces.java @@ -7,6 +7,8 @@ import de.monticore.cdinterfaceandenum._ast.ASTCDInterface; import de.monticore.symbols.oosymbols._symboltable.OOTypeSymbol; import de.monticore.types.mcbasictypes._ast.ASTMCObjectType; +import de.monticore.types.mcbasictypes._ast.ASTMCQualifiedType; +import de.monticore.types.mccollectiontypes._ast.ASTMCGenericType; import de.se_rwth.commons.logging.Log; import java.util.List; import java.util.Optional; @@ -26,14 +28,34 @@ public void check(ASTCDClass node) { return; } final List interfaceList = node.getCDInterfaceUsage().getInterfaceList(); - interfaceList.stream().map(s -> symbol.getEnclosingScope().resolveOOType(s.printType())).filter( - Optional::isPresent).map(Optional::get).filter(e -> !e.isIsInterface()).forEach(e -> Log - .error(String.format( + interfaceList.stream().map(s -> symbol.getEnclosingScope().resolveOOType(getObjectName(s))) + .filter(Optional::isPresent).map(Optional::get).filter(e -> !e.isIsInterface()).forEach( + e -> Log.error(String.format( "0xCDCF4: Class %s cannot implement %s %s. A class may only implement interfaces.", node.getName(), CDMill.cDTypeKindPrinter().print(e), e.getName()), node .get_SourcePositionStart())); } + protected String getObjectName(ASTMCObjectType type) { + // TODO: This is a fix for the following types: + // class State_Pat implements IState, IElem + // class Opt implements IElem + // interface IElem { } + // -> this tries to resolve "IElem.class", which fails HARD due to illegal chars! + // TODO: Discuss where to place such a thing + + if (type instanceof ASTMCQualifiedType qualifiedType) { + return qualifiedType.getMCQualifiedName().getQName(); + } + else if (type instanceof ASTMCGenericType genericType) { + return genericType.printWithoutTypeArguments(); + } + else { + throw new IllegalStateException("Unhandled MCObjectType " + type.getClass() + " of `" + type + .printType() + "` when trying to resolve source"); + } + } + /** * Actual check that the enums interfaces are really interfaces. * diff --git a/cdlang/src/main/java/de/monticore/cd/codegen/DecoratorConfig.java b/cdlang/src/main/java/de/monticore/cd/codegen/DecoratorConfig.java index b1f89ed27..b30a8c10f 100644 --- a/cdlang/src/main/java/de/monticore/cd/codegen/DecoratorConfig.java +++ b/cdlang/src/main/java/de/monticore/cd/codegen/DecoratorConfig.java @@ -96,6 +96,10 @@ public ChainableGenSetup withMethodImplementations() { return this.withDecorator(new MethodImplementationDecorator()); } + public ChainableGenSetup withRequiredArgsConstructors() { + return this.withDecorator(new RequiredArgsConstructorDecorator()); + } + @SuppressWarnings("unchecked") public ChainableGenSetup withDecorator(String className) { IDecorator newObj = (IDecorator) ObjectFactory.createObject(className); diff --git a/cdlang/src/main/java/de/monticore/cd/codegen/MCTypeFacadeFix.java b/cdlang/src/main/java/de/monticore/cd/codegen/MCTypeFacadeFix.java new file mode 100644 index 000000000..97d156d85 --- /dev/null +++ b/cdlang/src/main/java/de/monticore/cd/codegen/MCTypeFacadeFix.java @@ -0,0 +1,39 @@ +/* (c) https://github.com/MontiCore/monticore */ +package de.monticore.cd.codegen; + +import com.google.common.collect.Lists; +import de.monticore.cd4code.CD4CodeMill; +import de.monticore.types.mcbasictypes._ast.ASTMCType; +import de.monticore.types.mccollectiontypes._ast.ASTMCGenericType; +import de.monticore.types.mccollectiontypes._ast.ASTMCListType; +import de.monticore.types.mccollectiontypes._ast.ASTMCSetType; +import de.monticore.types.mcfullgenerictypes.MCFullGenericTypesMill; + +// TODO: Move this fix upstream if MCFullGenericTypes (?) is initialized +public class MCTypeFacadeFix { + + public static ASTMCListType createListTypeOf(final ASTMCType type) { + // Fix for IElem + var b = MCFullGenericTypesMill.mCListTypeBuilder(); + b.setMCTypeArgument(CD4CodeMill.mCCustomTypeArgumentBuilder().setMCType(type.deepClone()) + .build()); + return b.build(); + } + + public static ASTMCSetType createSetTypeOf(final ASTMCType type) { + // Fix for IElem + var b = MCFullGenericTypesMill.mCSetTypeBuilder(); + b.setMCTypeArgument(CD4CodeMill.mCCustomTypeArgumentBuilder().setMCType(type.deepClone()) + .build()); + return b.build(); + } + + public ASTMCGenericType createCollectionTypeOf(final ASTMCType type) { + var b = MCFullGenericTypesMill.mCBasicGenericTypeBuilder(); + b.setNamesList(Lists.newArrayList("Collection")); + b.addMCTypeArgument(CD4CodeMill.mCCustomTypeArgumentBuilder().setMCType(type.deepClone()) + .build()); + return b.build(); + } + +} diff --git a/cdlang/src/main/java/de/monticore/cd/codegen/decorators/CardinalityDefaultDecorator.java b/cdlang/src/main/java/de/monticore/cd/codegen/decorators/CardinalityDefaultDecorator.java index 10652ea95..a9c00c94d 100644 --- a/cdlang/src/main/java/de/monticore/cd/codegen/decorators/CardinalityDefaultDecorator.java +++ b/cdlang/src/main/java/de/monticore/cd/codegen/decorators/CardinalityDefaultDecorator.java @@ -3,6 +3,7 @@ import static de.monticore.cd.codegen.CD2JavaTemplates.EMPTY_BODY; +import com.google.common.collect.Iterables; import de.monticore.cd.codegen.decorators.data.AbstractDecorator; import de.monticore.cd.facade.CDConstructorFacade; import de.monticore.cd4code._visitor.CD4CodeTraverser; @@ -77,7 +78,7 @@ protected void decorateList(ASTCDClass decoratedClazz, ASTCDAttribute attribute) // Setting the initial value of the attribute fails, as // "new"/CreatorExpression is not part of CD4C glex.addAfterTemplate(EMPTY_BODY, c, new TemplateHookPoint("methods.Instantiation", attribute - .getName(), ArrayList.class.getName())))); + .getName(), ArrayList.class.getName() + "<>")))); } protected ASTModifier createModifier(ASTModifier original) { @@ -103,4 +104,11 @@ public void addToTraverser(CD4CodeTraverser traverser) { traverser.add4CDBasis(this); } + @Override + public Iterable> getMustRunAfter() { + // Constructors may be added here + return Iterables.concat(super.getMustRunAfter(), List.of( + RequiredArgsConstructorDecorator.class)); + } + } diff --git a/cdlang/src/main/java/de/monticore/cd/codegen/decorators/GetterDecorator.java b/cdlang/src/main/java/de/monticore/cd/codegen/decorators/GetterDecorator.java index 284aea2ce..525bfbf29 100644 --- a/cdlang/src/main/java/de/monticore/cd/codegen/decorators/GetterDecorator.java +++ b/cdlang/src/main/java/de/monticore/cd/codegen/decorators/GetterDecorator.java @@ -3,6 +3,7 @@ import static de.monticore.cd.codegen.CD2JavaTemplates.EMPTY_BODY; +import de.monticore.cd.codegen.MCTypeFacadeFix; import de.monticore.cd.codegen.decorators.data.AbstractDecorator; import de.monticore.cd.codegen.decorators.data.DecoratorData; import de.monticore.cd.facade.CDMethodFacade; @@ -130,7 +131,7 @@ protected MethodInformation decorateSet(ASTCDType decoratedType, ASTCDAttribute ASTMCType type = getCDGenService().getFirstTypeArgument(attribute.getMCType()).deepClone(); ASTCDMethod getListMethod = CDMethodFacade.getInstance().createMethod(attribute.getModifier() - .deepClone(), MCTypeFacade.getInstance().createSetTypeOf(type), name); + .deepClone(), MCTypeFacadeFix.createSetTypeOf(type), name); glexOpt.ifPresent(glex -> glex.replaceTemplate(EMPTY_BODY, getListMethod, new TemplateHookPoint( "methods.Get", attribute))); getListMethod.getModifier().setAbstract(attribute.getModifier().isDerived()); @@ -147,7 +148,7 @@ protected MethodInformation decorateList(ASTCDType decoratedType, ASTCDAttribute ASTMCType type = getCDGenService().getFirstTypeArgument(attribute.getMCType()).deepClone(); ASTCDMethod getListMethod = CDMethodFacade.getInstance().createMethod(attribute.getModifier() - .deepClone(), MCTypeFacade.getInstance().createListTypeOf(type), name); + .deepClone(), MCTypeFacadeFix.createListTypeOf(type), name); glexOpt.ifPresent(glex -> glex.replaceTemplate(EMPTY_BODY, getListMethod, new TemplateHookPoint( "methods.Get", attribute))); getListMethod.getModifier().setAbstract(attribute.getModifier().isDerived()); diff --git a/cdlang/src/main/java/de/monticore/cd/codegen/decorators/MethodImplementationDecorator.java b/cdlang/src/main/java/de/monticore/cd/codegen/decorators/MethodImplementationDecorator.java index 70e8ae4df..f381f9a99 100644 --- a/cdlang/src/main/java/de/monticore/cd/codegen/decorators/MethodImplementationDecorator.java +++ b/cdlang/src/main/java/de/monticore/cd/codegen/decorators/MethodImplementationDecorator.java @@ -29,11 +29,16 @@ public void visit(ASTCDMethod method) { } // TODO: ALu: Create shared get-marked value source (not only for stereotypes) - String template = method.getModifier().getStereotype().getValue("impl"); + + // TODO: Discuss if split via # or separate stereo is better for params? + String[] sp = method.getModifier().getStereotype().getValue("impl").split("#"); + String template = sp[0]; + Object[] templateParams = new Object[sp.length - 1]; + System.arraycopy(sp, 1, templateParams, 0, sp.length - 1); // And finally. replace the empty body template with the given template glexOpt.ifPresent(g -> g.replaceTemplate(CD4C.getInstance().getEmptyBodyTemplate(), - decoratorData.getAsDecorated(method), new TemplateHookPoint(template))); + decoratorData.getAsDecorated(method), new TemplateHookPoint(template, templateParams))); } } diff --git a/cdlang/src/main/java/de/monticore/cd/codegen/decorators/ObserverDecorator.java b/cdlang/src/main/java/de/monticore/cd/codegen/decorators/ObserverDecorator.java index f678c9de4..eaf1ec9fc 100644 --- a/cdlang/src/main/java/de/monticore/cd/codegen/decorators/ObserverDecorator.java +++ b/cdlang/src/main/java/de/monticore/cd/codegen/decorators/ObserverDecorator.java @@ -3,6 +3,7 @@ import com.google.common.collect.Iterables; import de.monticore.ast.ASTNode; +import de.monticore.cd.codegen.MCTypeFacadeFix; import de.monticore.cd.codegen.decorators.data.AbstractDecorator; import de.monticore.cd.facade.CDMethodFacade; import de.monticore.cd.facade.CDParameterFacade; @@ -72,7 +73,7 @@ public void visit(ASTCDClass clazz) { { //create an attribute of the type and the name of an observer ASTCDAttribute observerList = CD4CodeMill.cDAttributeBuilder().setName(OBS_LIST_ATTR) - .setMCType(MCTypeFacade.getInstance().createListTypeOf(observerInterfaceQualifiedType)) + .setMCType(MCTypeFacadeFix.createListTypeOf(observerInterfaceQualifiedType)) .setModifier(CD4CodeMill.modifierBuilder().PROTECTED().build()).build(); decClazz.addCDMember(observerList); diff --git a/cdlang/src/main/java/de/monticore/cd/codegen/decorators/RequiredArgsConstructorDecorator.java b/cdlang/src/main/java/de/monticore/cd/codegen/decorators/RequiredArgsConstructorDecorator.java new file mode 100644 index 000000000..aa84d79ac --- /dev/null +++ b/cdlang/src/main/java/de/monticore/cd/codegen/decorators/RequiredArgsConstructorDecorator.java @@ -0,0 +1,88 @@ +/* (c) https://github.com/MontiCore/monticore */ +package de.monticore.cd.codegen.decorators; + +import de.monticore.cd.codegen.decorators.data.AbstractDecorator; +import de.monticore.cd.facade.CDConstructorFacade; +import de.monticore.cd.facade.CDParameterFacade; +import de.monticore.cd.methodtemplates.CD4C; +import de.monticore.cd4code._visitor.CD4CodeTraverser; +import de.monticore.cd4codebasis._ast.ASTCDConstructor; +import de.monticore.cd4codebasis._visitor.CD4CodeBasisVisitor2; +import de.monticore.cdbasis._ast.ASTCDAttribute; +import de.monticore.cdbasis._ast.ASTCDClass; +import de.monticore.cdbasis._visitor.CDBasisVisitor2; +import de.monticore.generating.templateengine.TemplateHookPoint; +import de.monticore.umlmodifier.UMLModifierMill; +import de.monticore.umlmodifier._ast.ASTModifier; +import de.monticore.umlmodifier._ast.ASTModifierBuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * Provides method bodies of (modeled) methods from templates + * TODO: ALu - Add CI tests for this decorator (right now it is for playing around) + */ +public class RequiredArgsConstructorDecorator extends AbstractDecorator + implements CD4CodeBasisVisitor2, CDBasisVisitor2 { + + protected record StackData(List attrs) {} + + protected Stack stack = new Stack<>(); + + @Override + public void visit(ASTCDClass astcdClass) { + stack.push(new StackData(new ArrayList<>())); + } + + @Override + public void visit(ASTCDAttribute attribute) { + if (stack.isEmpty()) + return; + + // TODO: required vs all? + if (!attribute.getModifier().isFinal()) + return; + + if (decoratorData.shouldDecorate(this.getClass(), attribute)) + stack.peek().attrs.add(attribute); + } + + @Override + public void endVisit(ASTCDClass node) { + if (stack.isEmpty()) + return; + if (decoratorData.shouldDecorate(this.getClass(), node)) { + // TODO: Check that method does not already exists! + ASTCDConstructor constructor = CDConstructorFacade.getInstance().createConstructor( + copyVisibility(node.getModifier()), node.getName()); + for (ASTCDAttribute attribute : stack.peek().attrs()) { + constructor.addCDParameter(CDParameterFacade.getInstance().createParameter(attribute)); + } + + decoratorData.getAsDecorated(node).addCDMember(constructor); + + glexOpt.ifPresent(g -> g.replaceTemplate(CD4C.getInstance().getEmptyBodyTemplate(), + constructor, new TemplateHookPoint("methods.constructor.Constructor", stack + .peek().attrs))); + + stack.pop(); + } + } + + protected ASTModifier copyVisibility(ASTModifier orig) { + ASTModifierBuilder vis = UMLModifierMill.modifierBuilder(); + vis.setPublic(orig.isPublic()); + vis.setProtected(orig.isProtected()); + vis.setPrivate(orig.isPrivate()); + return vis.build(); + } + + @Override + public void addToTraverser(CD4CodeTraverser traverser) { + traverser.add4CD4CodeBasis(this); + traverser.add4CDBasis(this); + } + +} diff --git a/cdlang/src/main/java/de/monticore/cd/codegen/decorators/VisitorDecorator.java b/cdlang/src/main/java/de/monticore/cd/codegen/decorators/VisitorDecorator.java index 80a4b44c9..988d735ba 100644 --- a/cdlang/src/main/java/de/monticore/cd/codegen/decorators/VisitorDecorator.java +++ b/cdlang/src/main/java/de/monticore/cd/codegen/decorators/VisitorDecorator.java @@ -11,8 +11,8 @@ import de.monticore.cd4codebasis._ast.ASTCDInterface; import de.monticore.cd4codebasis._ast.ASTCDMethod; import de.monticore.cd4codebasis._ast.ASTCDParameter; -import de.monticore.cdbasis._ast.ASTCDClass; import de.monticore.cdbasis._ast.ASTCDDefinition; +import de.monticore.cdbasis._ast.ASTCDType; import de.monticore.cdbasis._visitor.CDBasisVisitor2; import de.monticore.generating.templateengine.TemplateHookPoint; import de.monticore.types.MCTypeFacade; @@ -78,10 +78,10 @@ public void endVisit(ASTCDDefinition clazz) { } @Override - public void visit(ASTCDClass clazz) { - if (decoratorData.shouldDecorate(this.getClass(), clazz)) { - ASTCDClass decClazz = decoratorData.getAsDecorated(clazz); - String packageName = clazz.getSymbol().getPackageName(); + public void visit(ASTCDType type) { + if (decoratorData.shouldDecorate(this.getClass(), type)) { + ASTCDType decClazz = decoratorData.getAsDecorated(type); + String packageName = type.getSymbol().getPackageName(); ASTCDInterface visitorInterface = getVisitorInterface(); @@ -93,7 +93,7 @@ public void visit(ASTCDClass clazz) { ASTCDParameter visitorParameter = CD4CodeMill.cDParameterBuilder().setName("visitor") .setMCType(visitorInterfaceQualifiedType).build(); //create a type of the class - ASTMCType classType = MCTypeFacade.getInstance().createQualifiedType(clazz.getName()); + ASTMCType classType = MCTypeFacade.getInstance().createQualifiedType(type.getName()); ASTCDParameter classParameter = CD4CodeMill.cDParameterBuilder().setName("node").setMCType( classType).build(); @@ -104,8 +104,7 @@ public void visit(ASTCDClass clazz) { // add the interface methods to the pojo class addToClass(decClazz, acceptMethod); glexOpt.ifPresent(glex -> glex.replaceTemplate(EMPTY_BODY, acceptMethod, - new TemplateHookPoint("methods.visitor.Accept", clazz.getName()))); - // new StringHookPoint("visitor.visit ((" + clazz.getName() + ")this);"))); + new TemplateHookPoint("methods.visitor.Accept", type.getName()))); CD4C.getInstance().addImport(decClazz, visitorInterfaceName); this.decParent.push(decClazz); @@ -118,13 +117,13 @@ public void visit(ASTCDClass clazz) { } @Override - public void endVisit(ASTCDClass clazz) { + public void endVisit(ASTCDType clazz) { if (decoratorData.shouldDecorate(this.getClass(), clazz)) { decParent.pop(); } } - protected Stack decParent = new Stack<>(); + protected Stack decParent = new Stack<>(); @Override public void addToTraverser(CD4CodeTraverser traverser) { diff --git a/cdlang/src/main/java/de/monticore/cd/codegen/decorators/VisitorImplementationDecorator.java b/cdlang/src/main/java/de/monticore/cd/codegen/decorators/VisitorImplementationDecorator.java index e94ac686a..9047a11dc 100644 --- a/cdlang/src/main/java/de/monticore/cd/codegen/decorators/VisitorImplementationDecorator.java +++ b/cdlang/src/main/java/de/monticore/cd/codegen/decorators/VisitorImplementationDecorator.java @@ -9,8 +9,10 @@ import de.monticore.cd.facade.CDMethodFacade; import de.monticore.cd4code.CD4CodeMill; import de.monticore.cd4code._visitor.CD4CodeTraverser; +import de.monticore.cd4codebasis._ast.ASTCDInterface; import de.monticore.cd4codebasis._ast.ASTCDMethod; import de.monticore.cd4codebasis._ast.ASTCDParameter; +import de.monticore.cd4codebasis._visitor.CD4CodeBasisVisitor2; import de.monticore.cdbasis._ast.ASTCDAttribute; import de.monticore.cdbasis._ast.ASTCDClass; import de.monticore.cdbasis._ast.ASTCDDefinition; @@ -34,7 +36,7 @@ * Applies the Visitor-Pattern to the CD */ public class VisitorImplementationDecorator extends AbstractDecorator - implements CDBasisVisitor2 { + implements CDBasisVisitor2, CD4CodeBasisVisitor2 { protected GetterDecorator.GetterData getterData; @@ -217,12 +219,30 @@ public void endVisit(ASTCDClass clazz) { } } + @Override + public void visit(ASTCDInterface cdInterface) { + if (decoratorData.shouldDecorate(this.getClass(), cdInterface)) { + ASTMCType classType = MCTypeFacade.getInstance().createQualifiedType(cdInterface.getName()); + ASTCDParameter classParameter = CD4CodeMill.cDParameterBuilder().setName("node").setMCType( + classType).build(); + + // add visit method + ASTCDMethod visitMethod = CDMethodFacade.getInstance().createMethod(CD4CodeMill + .modifierBuilder().PUBLIC().build(), "visit", classParameter); + getVisitorImplementationClass().addCDMember(visitMethod); + glexOpt.ifPresent(glex -> glex.replaceTemplate(EMPTY_BODY, visitMethod, new TemplateHookPoint( + "methods.visitor.DefaultVisit", (Object) null))); + + } + } + protected Stack visitMethodStack = new Stack<>(); protected Stack decParent = new Stack<>(); @Override public void addToTraverser(CD4CodeTraverser traverser) { traverser.add4CDBasis(this); + traverser.add4CD4CodeBasis(this); } } diff --git a/cdlang/src/main/java/de/monticore/cd4code/_parser/CD4CodeParser.java b/cdlang/src/main/java/de/monticore/cd4code/_parser/CD4CodeParser.java index dff0b86c1..35dc2d9a1 100644 --- a/cdlang/src/main/java/de/monticore/cd4code/_parser/CD4CodeParser.java +++ b/cdlang/src/main/java/de/monticore/cd4code/_parser/CD4CodeParser.java @@ -8,7 +8,24 @@ public class CD4CodeParser extends CD4CodeParserTOP { - boolean _checkFileAndPackageName = true; + protected boolean _checkFileAndPackageName; + + /** + * The parser for this grammar. + * {@link de.monticore.cd4code.CD4CodeMill#parser()} should be preferred over this constructor, as + * this further enables language composition. + * + * @deprecated new instances of a parser should be retrieved via a language's mill + */ + @Deprecated + public CD4CodeParser() { + this(true); + } + + @SuppressWarnings("deprecation") + public CD4CodeParser(boolean _checkFileAndPackageName) { + this._checkFileAndPackageName = _checkFileAndPackageName; + } @Override public Optional parse(String fileName) throws IOException { diff --git a/cdlang/src/main/java/de/monticore/cdbasis/cocos/ebnf/CDAttributeNameLowerCaseIfNotStatic.java b/cdlang/src/main/java/de/monticore/cdbasis/cocos/ebnf/CDAttributeNameLowerCaseIfNotStatic.java index 73f1793d2..07720cc5a 100644 --- a/cdlang/src/main/java/de/monticore/cdbasis/cocos/ebnf/CDAttributeNameLowerCaseIfNotStatic.java +++ b/cdlang/src/main/java/de/monticore/cdbasis/cocos/ebnf/CDAttributeNameLowerCaseIfNotStatic.java @@ -5,13 +5,14 @@ import de.monticore.cdbasis._cocos.CDBasisASTCDAttributeCoCo; import de.se_rwth.commons.logging.Log; -/** Checks that attribute names start lower-case. */ +/** Checks that attribute names start lower-case or underscore. */ public class CDAttributeNameLowerCaseIfNotStatic implements CDBasisASTCDAttributeCoCo { /** @see de.monticore.cdbasis._cocos.CDBasisASTCDAttributeCoCo#check(ASTCDAttribute) */ @Override public void check(ASTCDAttribute a) { - if (!a.getModifier().isStatic() && !Character.isLowerCase(a.getName().charAt(0))) { + if (!a.getModifier().isStatic() && !Character.isLowerCase(a.getName().charAt(0)) && a.getName() + .charAt(0) != '_') { Log.error(String.format("0xCDC03: Attribute %s must start in lower-case.", a.getName()), a .get_SourcePositionStart()); } diff --git a/cdlang/src/main/java/de/monticore/cdgen/CDGenTool.java b/cdlang/src/main/java/de/monticore/cdgen/CDGenTool.java index 76f461322..6fa0415a9 100644 --- a/cdlang/src/main/java/de/monticore/cdgen/CDGenTool.java +++ b/cdlang/src/main/java/de/monticore/cdgen/CDGenTool.java @@ -117,6 +117,9 @@ else if (!cmd.hasOption("i") || cmd.hasOption("h")) { return; } + // set up the log + setupLog(cmd); + final boolean c2mc = cmd.hasOption("c2mc"); initializeSymbolTable(c2mc, cmd.hasOption("class2mc-no-jdk")); @@ -389,7 +392,7 @@ public Options addAdditionalOptions(Options options) { .desc("Sets the path for additional, handwritten classes.").build()); options.addOption(Option.builder("c2mc").longOpt("class2mc").desc( - "Enables to resolve java classes in the model path").build()); + "Enables to resolve java classes in the model pat>h").build()); options.addOption(Option.builder().longOpt("class2mc-no-jdk").desc( "Does not resolve types from the installed JDK's standard library. Only the symbolpath is used.") diff --git a/cdlang/src/main/resources/cd2java/init/CD2Pojo.ftl b/cdlang/src/main/resources/cd2java/init/CD2Pojo.ftl index 4b8a5620d..9558ebc11 100644 --- a/cdlang/src/main/resources/cd2java/init/CD2Pojo.ftl +++ b/cdlang/src/main/resources/cd2java/init/CD2Pojo.ftl @@ -42,7 +42,8 @@ ${decConfig.withVisitors().applyOnName("visitor").ignoreOnName("noVisitor")} ${decConfig.withVisitorImplementations().applyOnName("visitor").ignoreOnName("noVisitor").ignoreOnName("noDefaultVisitor")} <#-- Similarly, the method implementation from templates decorator is NOT applied by default, unless an element or its parents are marked with impl --> ${decConfig.withMethodImplementations().applyOnName("impl").ignoreOnName("noImpl")} - +<#-- Similarly, the RequiredArgsConstructor decorator is NOT applied by default, unless a class or its parents are marked with requiredArgsConstructor --> +${decConfig.withRequiredArgsConstructors().applyOnName("requiredArgsConstructor").ignoreOnName("noRequiredArgsConstructor")} <#-- You can include & override the defaults by including this template diff --git a/cdlang/src/main/resources/cd2java/init/CD2PojoNoDefaults.ftl b/cdlang/src/main/resources/cd2java/init/CD2PojoNoDefaults.ftl index 1dd0887f1..01646e274 100644 --- a/cdlang/src/main/resources/cd2java/init/CD2PojoNoDefaults.ftl +++ b/cdlang/src/main/resources/cd2java/init/CD2PojoNoDefaults.ftl @@ -21,4 +21,5 @@ ${decConfig.withMethodImplementations().applyOnName("impl").ignoreOnName("noImpl ${decConfig.withVisitors().applyOnName("visitor").ignoreOnName("noVisitor")} ${decConfig.withVisitorImplementations().applyOnName("visitor").ignoreOnName("noVisitor").ignoreOnName("noDefaultVisitor")} ${decConfig.withMethodImplementations().applyOnName("impl").ignoreOnName("noImpl")} +${decConfig.withRequiredArgsConstructors().applyOnName("requiredArgsConstructor").ignoreOnName("noRequiredArgsConstructor")} diff --git a/cdlang/src/main/resources/methods/constructor/Constructor.ftl b/cdlang/src/main/resources/methods/constructor/Constructor.ftl new file mode 100644 index 000000000..55471dd27 --- /dev/null +++ b/cdlang/src/main/resources/methods/constructor/Constructor.ftl @@ -0,0 +1,8 @@ +<#-- (c) https://github.com/MontiCore/monticore --> +<#-- @ftlvariable name="tc" type="de.monticore.generating.templateengine.TemplateController" --> + +${tc.signature("attributes")} +<#list attributes as attr> +<#-- ${tc.includeArgs("methods.Set", attr)} # todo: new list?--> +this.${attr.getName()} = ${attr.getName()}; + diff --git a/doc/CDGen.md b/doc/CDGen.md index f487d144f..2955d6de0 100644 --- a/doc/CDGen.md +++ b/doc/CDGen.md @@ -16,7 +16,7 @@ all class diagrams in the _cds_ source-directory-set (e.g., _src/main/cds_, _src // build.gradle plugins { id 'java-library' - id 'de.rwth.se.cdgen' version '$mc_version' + id 'de.rwth.se.cdgen' version "$mc_version" } repositories {