Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Inferring type in variable declaration not working in interface generation(I am writing my DSL's Model inferrer, which extends from AbstractModelInferrer. Until now, I have successfully generated classes for some grammar constructs, however when I try to generate an interfac)
Inferring type in variable declaration not working in interface generation [message #1703102] Tue, 28 July 2015 14:38 Go to next message
Miguel Jimenez is currently offline Miguel JimenezFriend
Messages: 40
Registered: July 2015
Member
I am writing my DSL's Model inferrer, which extends from AbstractModelInferrer. Until now, I have successfully generated classes for some grammar constructs, however when I try to generate an interface the type inferrer does not work and I get the following Exception:

0 [Worker-2] ERROR org.eclipse.xtext.builder.BuilderParticipant - Error during compilation of 'platform:/resource/pascani/src/org/example/namespaces/SLA.pascani'.
java.lang.IllegalStateException: equivalent could not be computed

The Model inferrer code is:

def dispatch void infer(Namespace namespace, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
acceptor.accept(processNamespace(namespace, isPreIndexingPhase))
}

def JvmGenericType processNamespace(Namespace namespace, boolean isPreIndexingPhase) {
namespace.toInterface(namespace.fullyQualifiedName.toString) [
if (!isPreIndexingPhase) {
documentation = namespace.documentation
for (e : namespace.expressions) {
switch (e) {
Namespace: {
members +=
e.toMethod("get" + Strings.toFirstUpper(e.name), typeRef(e.fullyQualifiedName.toString)) [
abstract = true
]
members += processNamespace(e, isPreIndexingPhase);
}
XVariableDeclaration: {
members += processNamespaceVarDecl(e)
}
}
}
}
]
}

def processNamespaceVarDecl(XVariableDeclaration decl) {
val EList<JvmMember> members = new BasicEList();

val field = decl.toField(decl.name, inferredType(decl.right))[initializer = decl.right]
// members += field
members += decl.toMethod("get" + Strings.toFirstUpper(decl.name), field.type) [
abstract = true
]

if (decl.isWriteable) {
members += decl.toMethod("set" + Strings.toFirstUpper(decl.name), typeRef(Void.TYPE)) [
parameters += decl.toParameter(decl.name, field.type)
abstract = true
]
}

return members
}

I have tried using the lazy initializer after the acceptor.accept method, but it still does not work.

When I uncomment the line members += field, which adds a field to an interface, the model inferrer works fine; however, as you know, interfaces cannot have fields.

This seems like a bug to me. I have read tons of posts in the Eclipse forum but nothing seems to solve my problem. In case it is needed, this is my grammar:

grammar org.pascani.Pascani with org.eclipse.xtext.xbase.Xbase

import "http://www.eclipse.org/xtext/common/JavaVMTypes" as types
import "http://www.eclipse.org/xtext/xbase/Xbase"

generate pascani "http : // www . pascani . org / Pascani" // Eclipse forum thinks this is a link...

Model
: ('package' name = QualifiedName ->';'?)?
imports = XImportSection?
typeDeclaration = TypeDeclaration?
;

TypeDeclaration
: MonitorDeclaration
| NamespaceDeclaration
;

MonitorDeclaration returns Monitor
: 'monitor' name = ValidID
('using' usings += [Namespace | ValidID] (',' usings += [Namespace | ValidID])*)?
body = '{' expressions += InternalMonitorDeclaration* '}'
;

NamespaceDeclaration returns Namespace
: 'namespace' name = ValidID body = '{' expressions += InternalNamespaceDeclaration* '}'
;

InternalMonitorDeclaration returns XExpression
: XVariableDeclaration
| EventDeclaration
| HandlerDeclaration
;

InternalNamespaceDeclaration returns XExpression
: XVariableDeclaration
| NamespaceDeclaration
;

HandlerDeclaration
: 'handler' name = ValidID '(' param = FullJvmFormalParameter ')' body = XBlockExpression
;

EventDeclaration returns Event
: 'event' name = ValidID 'raised' (periodically ?= 'periodically')? 'on'? emitter = EventEmitter ->';'?
;

EventEmitter
: eventType = EventType 'of' emitter = QualifiedName (=> specifier = RelationalEventSpecifier)? ('using' probe = ValidID)?
| cronExpression = CronExpression
;

enum EventType
: invoke
| return
| change
| exception
;

RelationalEventSpecifier returns EventSpecifier
: EventSpecifier ({RelationalEventSpecifier.left = current} operator = RelationalOperator right = EventSpecifier)*
;

enum RelationalOperator
: and
| or
;

EventSpecifier
: (below ?= 'below' | above ?= 'above' | equal ?= 'equal' 'to') value = EventSpecifierValue
| '(' RelationalEventSpecifier ')'
;

EventSpecifierValue
: value = Number (percentage ?= '%')?
| variable = QualifiedName
;

CronExpression
: seconds = CronElement // 0-59
minutes = CronElement // 0-59
hours = CronElement // 0-23
days = CronElement // 1-31
months = CronElement // 1-2 or Jan-Dec
daysOfWeek = CronElement // 0-6 or Sun-Sat
| constant = CronConstant
;

enum CronConstant
: reboot // Run at startup
| yearly // 0 0 0 1 1 *
| annually // Equal to @yearly
| monthly // 0 0 0 1 * *
| weekly // 0 0 0 * * 0
| daily // 0 0 0 * * *
| hourly // 0 0 * * * *
| minutely // 0 * * * * *
| secondly // * * * * * *
;

CronElement
: RangeCronElement | PeriodicCronElement
;

RangeCronElement hidden()
: TerminalCronElement ({RangeCronElement.start = current} '-' end = TerminalCronElement)?
;

TerminalCronElement
: expression = (IntLiteral | ValidID | '*' | '?')
;

PeriodicCronElement hidden()
: expression = TerminalCronElement '/' elements = RangeCronList
;

RangeCronList hidden()
: elements += RangeCronElement (',' elements +=RangeCronElement)*
;

IntLiteral
: INT
;
Re: Inferring type in variable declaration not working in interface generation [message #1703143 is a reply to message #1703102] Tue, 28 July 2015 20:52 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
i dont know if that you are doing is a good idea.
the inferrer maps your concepts to java concepts and this enables the scoping for the expressions.
if you do not have a place for your expressions then it wont work. their types never will be computed

thus i think you have a usecase which is not possible using xbase without customizations.
your semantics is not quite clear to me.

i think the easiest would be to infer a class (with fields) as well

and then

		if (decl.isWriteable) {
			members += decl.toMethod("set" + Strings.toFirstUpper(decl.name), typeRef(Void.TYPE)) [
				parameters += decl.toParameter(decl.name, decl.right.inferredType)
				abstract = true
			]
		}


alternatively (with no guarantee to work in future)

	def processNamespaceVarDecl(XVariableDeclaration decl) {
		val EList<JvmMember> members = new BasicEList();

		//val field = decl.toField(decl.name, inferredType(decl.right))[initializer = decl.right]
// members += field
val gtr = decl.toMethod("get" + Strings.toFirstUpper(decl.name), decl.right.inferredType) [
			abstract = true
			body = decl.right
		]
		members += gtr

		if (decl.isWriteable) {
			members += decl.toMethod("set" + Strings.toFirstUpper(decl.name), typeRef(Void.TYPE)) [
				parameters += decl.toParameter(decl.name, decl.right.inferredType)
				abstract = true
			]
		}

		return members
	}


which works without an add. class


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Inferring type in variable declaration not working in interface generation [message #1703148 is a reply to message #1703143] Tue, 28 July 2015 21:27 Go to previous message
Miguel Jimenez is currently offline Miguel JimenezFriend
Messages: 40
Registered: July 2015
Member
Thanks Christian, I though I was doing something wrong. If it seems not to be a common use case, then there is no problem, I will make sure the user explicitly defines a variable type.

Just to clarify a little bit, a Namespace is intended to define variables that are used in Monitors. That's why a Namespace becomes an interface, and a Monitor becomes a class.

I discovered Xtend not so long ago and fell in love with implicit variables types and similar stuff Wink
Previous Topic:Simple question about the syntax tree
Next Topic:Reference a DSL from CDATA section in an Xml file
Goto Forum:
  


Current Time: Thu Apr 18 23:12:51 GMT 2024

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

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

Back to the top