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
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import de.monticore.cd._symboltable.CDSymbolTables;
import de.monticore.cd.facade.MCQualifiedNameFacade;
import de.monticore.cd4code.CD4CodeMill;
import de.monticore.cd4code.typescalculator.FullSynthesizeFromCD4Code;
import de.monticore.cdbasis._ast.ASTCDAttribute;
import de.monticore.cdbasis._ast.ASTCDType;
import de.monticore.cdconcretization.CompletionException;
Expand All @@ -14,6 +13,8 @@
import de.monticore.cdconcretization.util.NameUtil;
import de.monticore.symbols.basicsymbols._ast.ASTType;
import de.monticore.types.check.SymTypeExpression;
import de.monticore.types3.TypeCheck3;

import java.util.List;
import java.util.Optional;
import java.util.Set;
Expand Down Expand Up @@ -55,8 +56,7 @@ public void completeAttributeInType(ASTCDType concreteType, ASTCDAttribute refer
*/
private void createAttributeIncarnations(ASTCDType concreteType,
ASTCDAttribute referenceAttribute, TypeCompletionContext context) throws CompletionException {
SymTypeExpression attributeSymType = new FullSynthesizeFromCD4Code().synthesizeType(
referenceAttribute.getMCType()).getResult();
SymTypeExpression attributeSymType = TypeCheck3.symTypeFromAST(referenceAttribute.getMCType());

// make sure we do not add the 'any' type to the concrete CD
if (attributeSymType.getTypeInfo().getFullName().equals(context
Expand Down
1 change: 1 addition & 0 deletions cdlang/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ dependencies {
testImplementation testFixtures("de.monticore:monticore-grammar:$mc_version")

testFixturesImplementation "org.junit.jupiter:junit-jupiter-api:$junit_version"
testFixturesApi testFixtures("de.monticore:monticore-grammar:$mc_version")

//dependencies for trafo
if (withDSTLGen) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@
import de.monticore.cdinterfaceandenum._ast.ASTCDEnum;
import de.monticore.cdinterfaceandenum._ast.ASTCDInterface;
import de.monticore.symbols.oosymbols._symboltable.OOTypeSymbol;
import de.monticore.types.check.SymTypeExpression;
import de.monticore.types.mcbasictypes._ast.ASTMCObjectType;
import de.monticore.types.mcbasictypes._ast.ASTMCQualifiedType;
import de.monticore.types.mccollectiontypes._ast.ASTMCGenericType;
import de.monticore.types3.TypeCheck3;
import de.se_rwth.commons.logging.Log;
import java.util.List;
import java.util.Optional;

/** Checks that only interfaces are implemented. */
public abstract class ImplementOnlyInterfaces {

public static final String CLASS_ERROR_CODE = "0xCDCF4";
public static final String ENUM_ERROR_CODE = "0xCDCF5";
public static final String INTERFACE_ERROR_CODE = "0xCDCF6";

/**
* Actual check that the class's interfaces are really interfaces.
*
Expand All @@ -27,32 +29,23 @@ public void check(ASTCDClass node) {
if (!node.isPresentCDInterfaceUsage()) {
return;
}
final List<ASTMCObjectType> interfaceList = node.getCDInterfaceUsage().getInterfaceList();
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<IState>
// class Opt<T> implements IElem<T>
// interface IElem<T> { }
// -> this tries to resolve "IElem<T>.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");
for (ASTMCObjectType typeRef : node.getCDInterfaceUsage().getInterfaceList()) {
SymTypeExpression steRef = TypeCheck3.symTypeFromAST(typeRef);
if (steRef.hasTypeInfo()) {
if (!CoCoHelper.isInterface(steRef.getTypeInfo()))
Log.error(String.format(
"%s: Class %s cannot implement %s %s. A class may only implement interfaces.",
CLASS_ERROR_CODE, node.getName(), CDMill.cDTypeKindPrinter().print(steRef
.getTypeInfo()), steRef.getTypeInfo().getName()), node.get_SourcePositionStart());

}
else {
Log.error(String.format(
"%s: Class %s cannot implement <missing type info>. A class may only implement interfaces.",
CLASS_ERROR_CODE, node.getName()), node.get_SourcePositionStart());

}
}
}

Expand All @@ -68,10 +61,10 @@ public void check(ASTCDEnum node) {
}
symbol.streamSuperTypes().filter(i -> !CoCoHelper.isInterface(i.getTypeInfo())).forEach(e -> Log
.error(String.format(
"0xCDCF5: The %s %s cannot implement %s %s. Only interfaces may be implemented.", CDMill
.cDTypeKindPrinter().print(node), symbol.getName(), CDMill.cDTypeKindPrinter()
.print(e.getTypeInfo()), e.getTypeInfo().getName()), node
.get_SourcePositionStart()));
"%s: The %s %s cannot implement %s %s. Only interfaces may be implemented.",
ENUM_ERROR_CODE, CDMill.cDTypeKindPrinter().print(node), symbol.getName(), CDMill
.cDTypeKindPrinter().print(e.getTypeInfo()), e.getTypeInfo().getName()), node
.get_SourcePositionStart()));
}

/**
Expand All @@ -85,11 +78,10 @@ public void check(ASTCDInterface node) {
return;
}
symbol.streamSuperTypes().filter(i -> !CoCoHelper.isInterface(i.getTypeInfo())).forEach(e -> Log
.error(String.format(
"0xCDCF6: The %s %s cannot extend %s %s. Only interfaces may be extended.", CDMill
.cDTypeKindPrinter().print(node), symbol.getName(), CDMill.cDTypeKindPrinter()
.print(e.getTypeInfo()), e.getTypeInfo().getName()), node
.get_SourcePositionStart()));
.error(String.format("%s: The %s %s cannot extend %s %s. Only interfaces may be extended.",
INTERFACE_ERROR_CODE, CDMill.cDTypeKindPrinter().print(node), symbol.getName(), CDMill
.cDTypeKindPrinter().print(e.getTypeInfo()), e.getTypeInfo().getName()), node
.get_SourcePositionStart()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import de.monticore.cd.methodtemplates.CD4C;
import de.monticore.cd4code.CD4CodeMill;
import de.monticore.cd4code._visitor.CD4CodeTraverser;
import de.monticore.cd4codebasis._ast.ASTCDClass;
import de.monticore.cd4codebasis._ast.ASTCDInterface;
import de.monticore.cd4codebasis._ast.ASTCDMethod;
import de.monticore.cd4codebasis._ast.ASTCDParameter;
Expand All @@ -18,9 +19,14 @@
import de.monticore.types.MCTypeFacade;
import de.monticore.types.mcbasictypes._ast.ASTMCQualifiedType;
import de.monticore.types.mcbasictypes._ast.ASTMCType;
import de.monticore.types.mccollectiontypes._ast.ASTMCTypeArgument;
import de.monticore.types.mcfullgenerictypes._ast.ASTMCWildcardTypeArgumentBuilder;
import de.monticore.types.typeparameters._ast.ASTTypeParameter;
import de.se_rwth.commons.logging.Log;

import javax.annotation.Nullable;
import java.util.*;
import java.util.stream.Collectors;

import static de.monticore.cd.codegen.CD2JavaTemplates.EMPTY_BODY;

Expand Down Expand Up @@ -77,6 +83,17 @@
this._interfaceVisitorArtifact = null;
}

static ASTMCTypeArgument typeParamToArg(ASTTypeParameter parameter) {
ASTMCWildcardTypeArgumentBuilder wildcardTypeArgumentBuilder = CD4CodeMill
.mCWildcardTypeArgumentBuilder();
if (!parameter.getMCTypeList().isEmpty()) {
// without extends
Log.error("0xTODO: NYI multiple extends of ASTTypeParameter " + parameter, parameter

Check warning on line 91 in cdlang/src/main/java/de/monticore/cd/codegen/decorators/VisitorDecorator.java

View workflow job for this annotation

GitHub Actions / check-error-codes

ErrorCodeInvalid

Invalid error code 0xTODO (./cdlang/src/main/java/de/monticore/cd/codegen/decorators/VisitorDecorator.java:91)
.get_SourcePositionStart(), parameter.get_SourcePositionEnd());
}
return wildcardTypeArgumentBuilder.build();
}

@Override
public void visit(ASTCDType type) {
if (decoratorData.shouldDecorate(this.getClass(), type)) {
Expand All @@ -94,6 +111,26 @@
.setMCType(visitorInterfaceQualifiedType).build();
//create a type of the class
ASTMCType classType = MCTypeFacade.getInstance().createQualifiedType(type.getName());

// Workaround to add <?> type paras
if (type instanceof ASTCDClass typeOfClass) {
if (typeOfClass.isPresentTypeParameters() && !typeOfClass.getTypeParameters()
.getTypeParameterList().isEmpty()) {
classType = CD4CodeMill.mCBasicGenericTypeBuilder().addName(type.getName())
.addAllMCTypeArguments(typeOfClass.getTypeParameters().getTypeParameterList().stream()
.map(VisitorDecorator::typeParamToArg).collect(Collectors.toList())).build();
}
}
else if (type instanceof ASTCDInterface typeOfInterface) {
if (typeOfInterface.isPresentTypeParameters() && !typeOfInterface.getTypeParameters()
.getTypeParameterList().isEmpty()) {
classType = CD4CodeMill.mCBasicGenericTypeBuilder().addName(type.getName())
.addAllMCTypeArguments(typeOfInterface.getTypeParameters().getTypeParameterList()
.stream().map(VisitorDecorator::typeParamToArg).collect(Collectors.toList()))
.build();
}
}

ASTCDParameter classParameter = CD4CodeMill.cDParameterBuilder().setName("node").setMCType(
classType).build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.Objects;
import java.util.Optional;
import java.util.Stack;
import java.util.stream.Collectors;

import static de.monticore.cd.codegen.CD2JavaTemplates.EMPTY_BODY;

Expand Down Expand Up @@ -107,6 +108,15 @@
if (decoratorData.shouldDecorate(this.getClass(), clazz)) {
ASTCDClass decClazz = decoratorData.getAsDecorated(clazz);
ASTMCType classType = MCTypeFacade.getInstance().createQualifiedType(clazz.getName());
// Workaround to add <?> type paras
if (clazz instanceof de.monticore.cd4codebasis._ast.ASTCDClass typeOfClass) {
if (typeOfClass.isPresentTypeParameters() && !typeOfClass.getTypeParameters()
.getTypeParameterList().isEmpty()) {
classType = CD4CodeMill.mCBasicGenericTypeBuilder().addName(clazz.getName())
.addAllMCTypeArguments(typeOfClass.getTypeParameters().getTypeParameterList().stream()
.map(VisitorDecorator::typeParamToArg).collect(Collectors.toList())).build();
}
}
ASTCDParameter classParameter = CD4CodeMill.cDParameterBuilder().setName("node").setMCType(
classType).build();

Expand Down Expand Up @@ -148,7 +158,7 @@
if (attrInfo.getSymTypeExpression().getTypeInfo().isPresentAstNode() && !decoratorData
.shouldDecorate(VisitorDecorator.class, attrInfo.getSymTypeExpression().getTypeInfo()
.getAstNode())) {
warn(attribute, "0xTODO: Visitor implementation of association `" + attribute.getSymbol()

Check warning on line 161 in cdlang/src/main/java/de/monticore/cd/codegen/decorators/VisitorImplementationDecorator.java

View workflow job for this annotation

GitHub Actions / check-error-codes

ErrorCodeInvalid

Invalid error code 0xTODO (./cdlang/src/main/java/de/monticore/cd/codegen/decorators/VisitorImplementationDecorator.java:161)
.getFullName() + "` is not possible due to missing visitor of the class `" + attrInfo
.getSymTypeExpression().getTypeInfo().getFullName() + "`");
return;
Expand Down Expand Up @@ -199,7 +209,7 @@
}

protected void warnMissingGetter(ASTCDAttribute attribute) {
String message = "0xTODO: Attribute `" + attribute.getSymbol().getFullName()

Check warning on line 212 in cdlang/src/main/java/de/monticore/cd/codegen/decorators/VisitorImplementationDecorator.java

View workflow job for this annotation

GitHub Actions / check-error-codes

ErrorCodeInvalid

Invalid error code 0xTODO (./cdlang/src/main/java/de/monticore/cd/codegen/decorators/VisitorImplementationDecorator.java:212)
+ "` has no getter information provided. Unable to include in "
+ getVisitorImplementationClass().getName();
warn(attribute, message);
Expand All @@ -223,6 +233,12 @@
public void visit(ASTCDInterface cdInterface) {
if (decoratorData.shouldDecorate(this.getClass(), cdInterface)) {
ASTMCType classType = MCTypeFacade.getInstance().createQualifiedType(cdInterface.getName());
if (cdInterface.isPresentTypeParameters() && !cdInterface.getTypeParameters()
.getTypeParameterList().isEmpty()) {
classType = CD4CodeMill.mCBasicGenericTypeBuilder().addName(cdInterface.getName())
.addAllMCTypeArguments(cdInterface.getTypeParameters().getTypeParameterList().stream()
.map(VisitorDecorator::typeParamToArg).collect(Collectors.toList())).build();
}
ASTCDParameter classParameter = CD4CodeMill.cDParameterBuilder().setName("node").setMCType(
classType).build();

Expand Down
67 changes: 26 additions & 41 deletions cdlang/src/main/java/de/monticore/cd/methodtemplates/CD4C.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
import de.monticore.cd.codegen.methods.MutatorDecorator;
import de.monticore.cd4code.CD4CodeMill;
import de.monticore.cd4code._prettyprint.CD4CodeFullPrettyPrinter;
import de.monticore.cd4code.typescalculator.FullSynthesizeFromCD4Code;
import de.monticore.cd4codebasis._ast.ASTCD4CodeBasisNode;
import de.monticore.cd4codebasis._ast.ASTCDMethod;
import de.monticore.cd4codebasis._ast.ASTCDMethodSignature;
import de.monticore.cd4codebasis._cocos.CD4CodeBasisASTCDMethodSignatureCoCo;
Expand All @@ -24,9 +22,8 @@
import de.monticore.generating.templateengine.StringHookPoint;
import de.monticore.generating.templateengine.TemplateController;
import de.monticore.generating.templateengine.TemplateHookPoint;
import de.monticore.prettyprint.IndentPrinter;
import de.monticore.types.check.AbstractSynthesize;
import de.monticore.types.mcbasictypes._ast.ASTMCImportStatement;
import de.monticore.types3.TypeCheck3;
import de.se_rwth.commons.Joiners;
import de.se_rwth.commons.logging.Log;
import java.util.*;
Expand Down Expand Up @@ -62,9 +59,6 @@ public class CD4C {
protected final Map<ASTCDType, Set<ASTMCImportStatement>> importMap = Maps.newHashMap();

protected String emptyBodyTemplate = "de.monticore.cd.methodtemplates.core.EmptyMethod";
protected CD4CodeFullPrettyPrinter prettyPrinter = new CD4CodeFullPrettyPrinter(
new IndentPrinter(), true);
protected AbstractSynthesize typesCalculator = new FullSynthesizeFromCD4Code();

protected GeneratorSetup config;
protected boolean isInitialized;
Expand Down Expand Up @@ -139,12 +133,6 @@ protected static void checkInitialized() {
}

public CD4C setPrettyPrinter(CD4CodeFullPrettyPrinter prettyPrinter) {
this.prettyPrinter = prettyPrinter;
return this;
}

public CD4C setTypesCalculator(AbstractSynthesize typesCalculator) {
this.typesCalculator = typesCalculator;
return this;
}

Expand Down Expand Up @@ -217,7 +205,7 @@ public ASTCDMethodSignature addMethod(ASTCDType astcdType, String template, Obje
checkInitialized();

Optional<ASTCDMethodSignature> method = this.createMethod(astcdType, template, arguments);
if (!method.isPresent()) {
if (method.isEmpty()) {
Log.error("0x11010: There was no method created in the template '" + template + "'");
return null;
}
Expand Down Expand Up @@ -601,27 +589,25 @@ public CD4C addDefaultPredicates() {
addPredicate((m) -> {
final List<String> unknownTypes = m.getCDParameterList().stream().filter(p ->
// if parameter types are not valid/exist
!typesCalculator.synthesizeType(p.getMCType()).isPresentResult()).map(p -> prettyPrinter
.prettyprint(p.getMCType())).collect(Collectors.toList());
TypeCheck3.symTypeFromAST(p.getMCType()).isObscureType()).map(p -> CD4CodeMill.prettyPrint(p
.getMCType(), true)).collect(Collectors.toList());
if (unknownTypes.isEmpty()) {
return true;
}
else {
Log.error("0x110C0: The following types of the method signature (" + prettyPrinter
.prettyprint((ASTCD4CodeBasisNode) m) + ") could not be resolved '" + Joiners.COMMA
.join(unknownTypes) + "'.");
Log.error("0x110C0: The following types of the method signature (" + CD4CodeMill
.prettyPrint(m, true) + ") could not be resolved '" + Joiners.COMMA.join(unknownTypes)
+ "'.");
return false;
}
});
// check return type
addPredicate((m) -> {
if (m instanceof ASTCDMethod) {
final ASTCDMethod method = (ASTCDMethod) m;
if (!new FullSynthesizeFromCD4Code().synthesizeType(method.getMCReturnType())
.isPresentResult()) {
Log.error("0x110C1: The return type '" + prettyPrinter.prettyprint(method
.getMCReturnType()) + "' of the method signature (" + prettyPrinter.prettyprint(
(ASTCD4CodeBasisNode) m) + ") could not be resolved.");
if (m instanceof ASTCDMethod method) {
if (TypeCheck3.symTypeFromAST(method.getMCReturnType()).isObscureType()) {
Log.info("0x110C1: The return type '" + CD4CodeMill.prettyPrint(method.getMCReturnType(),
true) + "' of the method signature (" + CD4CodeMill.prettyPrint(m, true)
+ ") could not be resolved.", "CD4C");
return false;
}
}
Expand All @@ -632,11 +618,12 @@ public CD4C addDefaultPredicates() {
// attributes
// check type
addAttributePredicate((attribute) -> {
if (!new FullSynthesizeFromCD4Code().synthesizeType(attribute.getMCType())
.isPresentResult()) {
Log.error("0x110C2: The type '" + prettyPrinter.prettyprint(attribute.getMCType())
+ "' of the attribute declaration (" + prettyPrinter.prettyprint(attribute)
+ ") could not be resolved.");
if (TypeCheck3.symTypeFromAST(attribute.getMCType()).isObscureType()) {
// The error is already printed by the IDerive visitors, thus we would spam the log if we would log an error
// again. Therefore, we only leave a note in the debug log.
Log.debug("0x110C2: The type '" + CD4CodeMill.prettyPrint(attribute.getMCType(), true)
+ "' of the attribute declaration (" + CD4CodeMill.prettyPrint(attribute, true)
+ ") could not be resolved.", getClass().getName());
return false;
}

Expand Down Expand Up @@ -675,13 +662,12 @@ public CD4C addClassPredicate(BiPredicate<ASTCDType, ASTCDMethodSignature> predi
public CD4C addDefaultClassPredicates() {
// methods
addClassPredicate((c, m) -> {
final List<String> parameterTypes = m.getCDParameterList().stream().map(p -> typesCalculator
.synthesizeType(p.getMCType()).getResult().getTypeInfo().getFullName()).collect(Collectors
.toList());
final List<String> parameterTypes = m.getCDParameterList().stream().map(p -> TypeCheck3
.symTypeFromAST(p.getMCType()).getTypeInfo().getFullName()).collect(Collectors.toList());
if (c.getCDMethodSignatureList().stream().anyMatch(cm -> {
final List<String> parameter = cm.getCDParameterList().stream().map(p -> typesCalculator
.synthesizeType(p.getMCType()).getResult().getTypeInfo().getFullName()).collect(
Collectors.toList());
final List<String> parameter = cm.getCDParameterList().stream().map(p -> TypeCheck3
.symTypeFromAST(p.getMCType()).getTypeInfo().getFullName()).collect(Collectors
.toList());
return m.getName().equals(cm.getName()) && Iterables.elementsEqual(parameterTypes,
parameter);
})) {
Expand All @@ -694,10 +680,9 @@ public CD4C addDefaultClassPredicates() {

// attributes
addAttrClassPredicate((c, a) -> {
final String attrType = typesCalculator.synthesizeType(a.getMCType()).getResult()
.getTypeInfo().getFullName();
if (c.getCDAttributeList().stream().anyMatch(ca -> attrType.equals(typesCalculator
.synthesizeType(ca.getMCType()).getResult().getTypeInfo().getFullName()))) {
final String attrType = TypeCheck3.symTypeFromAST(a.getMCType()).getTypeInfo().getFullName();
if (c.getCDAttributeList().stream().anyMatch(ca -> attrType.equals(TypeCheck3.symTypeFromAST(
ca.getMCType()).getTypeInfo().getFullName()))) {
Log.error("0x110C9: The class '" + c.getName() + "' already has a attribute named '" + a
.getName() + "'");
return false;
Expand Down
Loading
Loading