I'm having trouble looping over an Integer size in my model. In the for loop below, I try to extract the Integer with a query. The query works fine when I run it in a template alone and it is clearly generating out the correct modeled integer value. However when I attempt to loop over the number modeled (see below), I get an error that the first and last types in the Sequence{} do not match. I don't understand since the query returns an Integer type, doesn't that match the type of the value 1 in the Sequence?

I certainly had similar troubles when I had the org.eclipse.ocl.ecore
project open in my workspace. Acceleo suffers from metamodel
schizophrenia and so thinks it has more than one Integer type. The
workaround is to use let variables to simplify expressions.

Regards

Ed Willink

On 21/07/2016 16:06, Missing name Mising name wrote:
> I'm having trouble looping over an Integer size in my model. In the
> for loop below, I try to extract the Integer with a query. The query
> works fine when I run it in a template alone and it is clearly
> generating out the correct modeled integer value. However when I
> attempt to loop over the number modeled (see below), I get an error
> that the first and last types in the Sequence{} do not match. I don't
> understand since the query returns an Integer type, doesn't that match
> the type of the value 1 in the Sequence?
>
>
> [query public dimensionSize(anArrayDim : ArrayDimension) : Integer =
> anArrayDim.size /]
>
> [template public cppVariablePrintout(field : Array)]
> [for (Sequence{1..field.dimensions->first().dimensionSize()})]
> [field.dimensions->first().dimensionSize()/]
> [/for]
> [/template]
>

Thank you very much for the quick reply. I tried using a let statement as Ed suggested and unfortunately received the same error. Here is the error text:

org.eclipse.acceleo.engine.AcceleoEvaluationException: Unresolved compilation error, expression was null.
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1886)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoForBlock(AcceleoEvaluationVisitor.java:448)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1913)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoTemplate(AcceleoEvaluationVisitor.java:921)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1897)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoTemplateInvocation(AcceleoEvaluationVisitor.java:972)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1936)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoForBlock(AcceleoEvaluationVisitor.java:537)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1913)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoFileBlock(AcceleoEvaluationVisitor.java:431)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1926)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoTemplate(AcceleoEvaluationVisitor.java:921)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1897)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoTemplateInvocation(AcceleoEvaluationVisitor.java:972)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1936)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
at org.eclipse.ocl.internal.evaluation.IterationTemplate.evaluate(IterationTemplate.java:81)
at org.eclipse.ocl.EvaluationVisitorImpl.evaluateCollectIterator(EvaluationVisitorImpl.java:1968)
at org.eclipse.ocl.EvaluationVisitorImpl.visitIteratorExp(EvaluationVisitorImpl.java:1818)
at org.eclipse.ocl.EvaluationVisitorDecorator.visitIteratorExp(EvaluationVisitorDecorator.java:235)
at org.eclipse.ocl.ecore.impl.IteratorExpImpl.accept(IteratorExpImpl.java:108)
at org.eclipse.ocl.AbstractEvaluationVisitor.visitExpression(AbstractEvaluationVisitor.java:242)
at org.eclipse.ocl.EvaluationVisitorDecorator.visitExpression(EvaluationVisitorDecorator.java:150)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1965)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoTemplate(AcceleoEvaluationVisitor.java:921)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1897)
at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
at org.eclipse.ocl.internal.evaluation.QueryImpl.evaluate(QueryImpl.java:146)
at org.eclipse.ocl.ecore.QueryImpl.evaluate(QueryImpl.java:56)
at org.eclipse.acceleo.engine.generation.AcceleoEngine.doEvaluate(AcceleoEngine.java:365)
at org.eclipse.acceleo.engine.generation.AcceleoEngine.evaluate(AcceleoEngine.java:142)
at org.eclipse.acceleo.engine.service.AcceleoService.doGenerateTemplate(AcceleoService.java:984)
at org.eclipse.acceleo.engine.service.AcceleoService.doGenerate(AcceleoService.java:641)
at org.eclipse.acceleo.engine.service.AbstractAcceleoGenerator.generate(AbstractAcceleoGenerator.java:209)
at org.eclipse.acceleo.engine.service.AbstractAcceleoGenerator.generate(AbstractAcceleoGenerator.java:172)
at org.eclipse.acceleo.engine.service.AbstractAcceleoGenerator.doGenerate(AbstractAcceleoGenerator.java:159)
at messaging.gen.main.Main.doGenerate(Main.java:204)
at messaging.gen.main.Main.main(Main.java:162)
org.eclipse.acceleo.engine.AcceleoEvaluationException: Invalid loop iteration at line 39 in Module fieldShared for block for. Last recorded value of self was messaging.fields.impl.ArrayImpl@40754382 (name: errorList, interpretation: null) (sizeType: UNSIGNED_BYTE). Problem found while generating the file 'C:\Users\Tom\workspace\iam\shared\src\messaging\messages\ReportErrors.cpp'.
at fieldShared.cppVariablePrintout(Array)(fieldShared.mtl:39)
at fieldShared.cppVariablePrintout(Array)(fieldShared.mtl:37)
at messageCpp.messageCpp(Message)(messageCpp.mtl:0)
at messageCpp.messageCpp(Message)(messageCpp.mtl:95)
at messageCpp.messageCpp(Message)(messageCpp.mtl:7)
at messageCpp.messageCpp(Message)(messageCpp.mtl:5)
at main.main(System)(main.mtl:0)
at main.main(System)(main.mtl:0)
at main.main(System)(main.mtl:20)

Laurent, I also tried simply to generate the text result of the query and indeed I get the expected value. In my test model my "arraySize" equals 6 and in the generated file I see a printed value of "6".

Also the attached image shows what I see in my mtl editor. The associated error problem is "First and last type mismatch: (1..myIntArraySize)"

Try putting "1" in a let variable too. If your problem is metamodel
schizophrenia, you must use identical types in paired situations. And
make really sure a rebuild has occurred. In the past I found that time
could be wasted debugging a stale compilation.

Regards

Ed Willink

On 22/07/2016 20:12, Tom Galluzzo wrote:
> Ed, and Laurent,
>
> Thank you very much for the quick reply. I tried using a let statement as Ed suggested and unfortunately received the same error. Here is the error text:
>
>
> org.eclipse.acceleo.engine.AcceleoEvaluationException: Unresolved compilation error, expression was null.
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1886)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoForBlock(AcceleoEvaluationVisitor.java:448)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1913)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoTemplate(AcceleoEvaluationVisitor.java:921)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1897)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoTemplateInvocation(AcceleoEvaluationVisitor.java:972)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1936)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoForBlock(AcceleoEvaluationVisitor.java:537)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1913)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoFileBlock(AcceleoEvaluationVisitor.java:431)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1926)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoTemplate(AcceleoEvaluationVisitor.java:921)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1897)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoTemplateInvocation(AcceleoEvaluationVisitor.java:972)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1936)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
> at org.eclipse.ocl.internal.evaluation.IterationTemplate.evaluate(IterationTemplate.java:81)
> at org.eclipse.ocl.EvaluationVisitorImpl.evaluateCollectIterator(EvaluationVisitorImpl.java:1968)
> at org.eclipse.ocl.EvaluationVisitorImpl.visitIteratorExp(EvaluationVisitorImpl.java:1818)
> at org.eclipse.ocl.EvaluationVisitorDecorator.visitIteratorExp(EvaluationVisitorDecorator.java:235)
> at org.eclipse.ocl.ecore.impl.IteratorExpImpl.accept(IteratorExpImpl.java:108)
> at org.eclipse.ocl.AbstractEvaluationVisitor.visitExpression(AbstractEvaluationVisitor.java:242)
> at org.eclipse.ocl.EvaluationVisitorDecorator.visitExpression(EvaluationVisitorDecorator.java:150)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1965)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitAcceleoTemplate(AcceleoEvaluationVisitor.java:921)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.switchExpression(AcceleoEvaluationVisitor.java:1897)
> at org.eclipse.acceleo.engine.internal.evaluation.AcceleoEvaluationVisitor.visitExpression(AcceleoEvaluationVisitor.java:1049)
> at org.eclipse.ocl.internal.evaluation.QueryImpl.evaluate(QueryImpl.java:146)
> at org.eclipse.ocl.ecore.QueryImpl.evaluate(QueryImpl.java:56)
> at org.eclipse.acceleo.engine.generation.AcceleoEngine.doEvaluate(AcceleoEngine.java:365)
> at org.eclipse.acceleo.engine.generation.AcceleoEngine.evaluate(AcceleoEngine.java:142)
> at org.eclipse.acceleo.engine.service.AcceleoService.doGenerateTemplate(AcceleoService.java:984)
> at org.eclipse.acceleo.engine.service.AcceleoService.doGenerate(AcceleoService.java:641)
> at org.eclipse.acceleo.engine.service.AbstractAcceleoGenerator.generate(AbstractAcceleoGenerator.java:209)
> at org.eclipse.acceleo.engine.service.AbstractAcceleoGenerator.generate(AbstractAcceleoGenerator.java:172)
> at org.eclipse.acceleo.engine.service.AbstractAcceleoGenerator.doGenerate(AbstractAcceleoGenerator.java:159)
> at messaging.gen.main.Main.doGenerate(Main.java:204)
> at messaging.gen.main.Main.main(Main.java:162)
> org.eclipse.acceleo.engine.AcceleoEvaluationException: Invalid loop iteration at line 39 in Module fieldShared for block for. Last recorded value of self was messaging.fields.impl.ArrayImpl@40754382 (name: errorList, interpretation: null) (sizeType: UNSIGNED_BYTE). Problem found while generating the file 'C:\Users\Tom\workspace\iam\shared\src\messaging\messages\ReportErrors.cpp'.
> at fieldShared.cppVariablePrintout(Array)(fieldShared.mtl:39)
> at fieldShared.cppVariablePrintout(Array)(fieldShared.mtl:37)
> at messageCpp.messageCpp(Message)(messageCpp.mtl:0)
> at messageCpp.messageCpp(Message)(messageCpp.mtl:95)
> at messageCpp.messageCpp(Message)(messageCpp.mtl:7)
> at messageCpp.messageCpp(Message)(messageCpp.mtl:5)
> at main.main(System)(main.mtl:0)
> at main.main(System)(main.mtl:0)
> at main.main(System)(main.mtl:20)
>
>
> Laurent, I also tried simply to generate the text result of the query and indeed I get the expected value. In my test model my "arraySize" equals 6 and in the generated file I see a printed value of "6".
>
> Also the attached image shows what I see in my mtl editor. The associated error problem is "First and last type mismatch: (1..myIntArraySize)"
>
>
>

Ok I got it working. I actually had two problems. The first was metamodel Schizophrenia within my own metamodel, which defined a class called "Integer". I can see now why that was very bad. The second was that my "arrayDim.size" type was metamodeled as an "Elong" which wasn't compatible with Acceleo "for" loop or "let" statement assignments for some reason. I needed to switch the metamodel of the size to "Int [int]" in my ecore model.

Any idea why casting an Elong to an Integer in acceleo would cause a let or for loop statement not to execute? Just curious for my own learning.

Ok I got it working. I actually had two problems. The first was metamodel Schizophrenia within my own metamodel, which defined a class called "Integer". I can see now why that was very bad.

Actually, this is a use case that should work in Acceleo if I'm not mistaken.

Quote:

The second was that my "arrayDim.size" type was metamodeled as an "Elong" which wasn't compatible with Acceleo "for" loop or "let" statement assignments for some reason. I needed to switch the metamodel of the size to "Int [int]" in my ecore model.

Any idea why casting an Elong to an Integer in acceleo would cause a let or for loop statement not to execute? Just curious for my own learning.

This is your real issue. EMF will not consider an integer to be compatible with type ELong, so Acceleo won't either. That is due to how "isInstance" checks are implemented in EMF, you can take a look at EClassifier.isInstance(Object) for your information. Basically, for the "ELong" classifier, the only object that will be considered compatible are instances of "java.lang.Long", which integers are not.

The revised Pivot OCL implementation associates an optional
behavioralType with each DataType, so that e.g. ELong has an Integer
behavioralType. The OCLforUML profile supports configuring this for
arbitrary user types. For DataTypes with an instance class, the known
Java types are mapped to Inreger / Real.

The use of isInstance() for DataTypes is very suspect, so perhaps you
have a bug to fix (or to report against the Classic OCL).

My view of precision in OCL (and OCL-extending tools) is:

a) User types are loaded from model
b) OCL evaluations proceed, using the behavioral type where necessary
resulting in Integer/Real internal working variables
c) OCL results are saved to the model with Integer/Real
validated/converted to fit the model element's type

Regards

Ed Willink

On 25/07/2016 09:07, Laurent Goubet wrote:
> Quote:
>> The second was that my "arrayDim.size" type was metamodeled as an
>> "Elong" which wasn't compatible with Acceleo "for" loop or "let"
>> statement assignments for some reason. I needed to switch the
>> metamodel of the size to "Int [int]" in my ecore model.
>>
>> Any idea why casting an Elong to an Integer in acceleo would cause a
>> let or for loop statement not to execute? Just curious for my own
>> learning.
>
>
> This is your real issue. EMF will not consider an integer to be
> compatible with type ELong, so Acceleo won't either. That is due to
> how "isInstance" checks are implemented in EMF, you can take a look at
> EClassifier.isInstance(Object) for your information. Basically, for
> the "ELong" classifier, the only object that will be considered
> compatible are instances of "java.lang.Long", which integers are not.
>
> Laurent Goubet
> Obeo
>