Dear all.
I would like to support the classic "assert" in my DSL.
The rule in my grammar is:
AssertExpression returns xbase::XExpression :
{SarlAssertExpression}
'assert' (->condition=XExpression) (->',' message=STRING)?
;
My Ecore model and GenModel contain the definition of SarlAssertExpression with the "condition" and "message" fields.
I have overriden the XtendCompiler and XbaseCompiler with:
class SarlCompiler extends XtendCompiler {
public void doInternalToJavaStatement(XExpression obj, ITreeAppendable appendable, boolean isReferenced) {
if (obj instanceof SarlAssertExpression) {
_toJavaStatement((SarlAssertExpression) obj, appendable, isReferenced);
} else {
super.doInternalToJavaStatement(obj, appendable, isReferenced);
}
}
public void internalToConvertedExpression(XExpression obj, ITreeAppendable appendable) {
if (obj instanceof SarlAssertExpression) {
_toJavaExpression((SarlAssertExpression) obj, appendable);
} else {
super.internalToConvertedExpression(obj, appendable);
}
}
protected void _toJavaStatement(SarlAssertExpression assertExpression, ITreeAppendable appendable, boolean isReferenced) {
if (assertExpression.getCondition() != null) {
final XExpression condition = assertExpression.getCondition();
appendable.newLine().append("assert ");
final Boolean booleanConstant = this.sarlExpressionHelper.toBooleanPrimitiveWrapperConstant(condition);
if (booleanConstant != null) {
appendable.append(booleanConstant.toString());
} else {
final LightweightTypeReference actualType = getLightweightType(condition);
if (actualType != null &&
(actualType.isAssignableFrom(boolean.class) || (actualType.isAssignableFrom(Boolean.class)))) {
appendable.append("(");
appendable.append(Function0.class);
appendable.append("<Boolean>) () -> {");
appendable.increaseIndentation();
internalToJavaStatement(condition, appendable, true);
appendable.newLine();
appendable.append("return (");
internalToConvertedExpression(condition, appendable, actualType);
appendable.append(");");
appendable.decreaseIndentation().newLine();
appendable.append("}).apply().booleanValue()");
} else {
appendable.append("true /* illegal expression type */");
}
}
if (!Strings.isEmpty(assertExpression.getMessage())) {
appendable.append(" : \"");
appendable.append(Strings.convertToJavaString(assertExpression.getMessage()));
appendable.append("\"");
}
appendable.append(";");
}
}
protected void _toJavaExpression(SarlAssertExpression assertExpression, ITreeAppendable appendable) {
appendable.append("/* error - couldn't compile nested assert */");
}
protected boolean internalCanCompileToJavaExpression(XExpression expression, ITreeAppendable appendable) {
if (expression instanceof SarlAssertExpression) {
return true;
}
return super.internalCanCompileToJavaExpression(expression, appendable);
}
protected boolean isVariableDeclarationRequired(XExpression expression, ITreeAppendable appendable, boolean recursive) {
final EObject container = expression.eContainer();
if (container instanceof SarlAssertExpression) {
return false;
}
return super.isVariableDeclarationRequired(expression, appendable, recursive);
}
}
I have also overridden the TypeComputer with:
public void computeTypes(XExpression expression, ITypeComputationState state) {
if (expression instanceof SarlAssertExpression) {
_computeTypes((SarlAssertExpression) expression, state);
} else {
super.computeTypes(expression, state);
}
}
protected void _computeTypes(SarlAssertExpression object, ITypeComputationState state) {
final LightweightTypeReference primitiveVoid = getPrimitiveVoid(state);
state.acceptActualType(primitiveVoid);
}
My problem is: the actual type of assert "condition" cannot be computed by the type resolver into the SarlCompiler. The call to "getLightweightType(condition)" replies an actual type equals to null.
The failing DSL code example is:
agent A1 {
def fct1(x : int) : int {
assert x > 0
return x + 1
}
def fct2(x : int) : int {
if (x > 0) {}
return x + 1
}
}
What have I missed to define?
Thank you by advance.
Stéphane.
[Updated on: Mon, 28 August 2017 09:39]
Report message to a moderator