Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » [SOLVED] Simple "assert" support(NPE when compiling "assert" conditions.)
[SOLVED] Simple "assert" support [message #1771556] Sun, 27 August 2017 22:31 Go to next message
Stéphane Galland is currently offline Stéphane GallandFriend
Messages: 123
Registered: July 2014
Location: Belfort, France
Senior Member
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

Re: Simple "assert" support [message #1771561 is a reply to message #1771556] Mon, 28 August 2017 03:48 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
I would have expected that you call (pseudocode)

State.withexpectation(Boolean).computeTypes (condition)


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Simple "assert" support [message #1771581 is a reply to message #1771561] Mon, 28 August 2017 09:38 Go to previous message
Stéphane Galland is currently offline Stéphane GallandFriend
Messages: 123
Registered: July 2014
Location: Belfort, France
Senior Member
Dear Christian.
Your recommandation solves my issue.
Thank you.
Stéphane.
Previous Topic:Couldn't resolve reference to *** problem
Next Topic:ValueConverter
Goto Forum:
  


Current Time: Tue Mar 19 05:04:43 GMT 2024

Powered by FUDForum. Page generated in 0.04345 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top