Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Null properties of the EObject in the ScopeProvider
Null properties of the EObject in the ScopeProvider [message #1804006] Fri, 15 March 2019 12:24 Go to next message
kozhaev Vladimir is currently offline kozhaev VladimirFriend
Messages: 108
Registered: July 2009
Senior Member
Hi all. I have make the grammar and the ScopeProvider(please, see it below) and get the null pointer exception.

Quote:

class foo { key k: integer; mutable name; }
operation op() {
update foo @{foo.k == 122}(name = "new_name");
}


It means, that in the following rule classRef equals to null. But really it's not.
How to solve this problem?
Regards, Vladimir

0    [main] ERROR xt.linking.lazy.LazyLinkingResource  - resolution of uriFragment '|2' failed.
java.lang.NullPointerException
	at org.blockchain.rell.scoping.RellScopeProvider.getVarDeclList(RellScopeProvider.java:273)
	at org.blockchain.rell.scoping.RellScopeProvider.getVariableDeclarationRefScope(RellScopeProvider.java:91)
	at org.blockchain.rell.scoping.RellScopeProvider.getScope(RellScopeProvider.java:314)


grammar org.blockchain.rell.Rell with org.eclipse.xtext.common.Terminals

generate rell "http://www.blockchain.org/rell/Rell"

Model:
	entities+=ClassDefinition*
	operations+=Operation*;

ClassDefinition:
	('class' | 'record') name=ID ('extends' superType=[ClassDefinition])? '{'
	attributeListField+=AttributeListField*
	'}';

AttributeListField:
	mutable=Mutable? key=Key? index=Index? attributeList+=RelAttrubutesList ';';

Operation:
	"operation" name=ID "(" parameters=RelAttrubutesList? ")" "{" statements+=Statement* "}";


Statement:
	(methodCall=DotValue|relation=Update | variable=OperationVariable | varInitiation=VarInitiation) ';';

VarInitiation:
	name=VariableDeclarationRef (('[' expr=Expression']')?) (ASSIGNMENT expression=Expression)?;

OperationVariable:
	assessModificator=(Var | Val) variable=Variable;

Variable:
	name=VariableDeclaration ((ASSIGNMENT expression=Expression)?);


Update:
	'update' entity=TableNameWithAlias (('@' '{' ((conditions+=Expression (',' conditions+=Expression)*)?) '}')?) '('
	createWhatPart+=CreateWhatPart (','
	createWhatPart+=CreateWhatPart)*
	')';

CreateWhatPart:
	 (DOT? varDeclRef=VariableDeclarationRef ASSIGNMENT)?
	condition+=Expression;



ClassMemberDefinition:
	(classRef=[TableNameWithAlias])? DOT (variableDeclarationRef=VariableDeclarationRef);



TableNameWithAlias:
	classRefDecl=ClassRefDecl |
	justNameDecl=JustNameDecl;



ClassRefDecl:name=ID DOUBLE_QUOTE classDef=[ClassDefinition];
JustNameDecl:name=[ClassDefinition];

VariableDeclarationRef:
	name=[VariableDeclaration|ValuableID];




AccessToList:
	'[' expr=Expression ']';

Expression:
	or=Or;

Or returns Expression:
	And ({Or.left=current} "or" right=And)*;

And returns Expression:
	Equality ({And.left=current} "and" right=Equality)*;

Equality returns Expression:
	Comparison ({Equality.left=current} op=EQUALS
	right=Comparison)*;

Comparison returns Expression:
	PlusOrMinus ({Comparison.left=current} op=EQUALS
	right=PlusOrMinus)*;

PlusOrMinus returns Expression:
	MulOrDiv (({Plus.left=current} PlusChar | {Minus.left=current} MinusChar)
	right=MulOrDiv)*;

MulOrDiv returns Expression:
	Primary ({MulOrDiv.left=current} op=(MulChar | DivChar)
	right=Primary)*;

Primary returns Expression:
	'(' Expression ')' |
	{Not} "not" expression=Primary |
	DotValue;
	

Atomic returns Expression:
	{IntConstant} value=IntWithMinus 
	|{StringConstant} value=STRING |
	{ByteArrayConstant} value=BYTE_ARRAY_VALUE |
	{BoolConstant} value=('true' | 'false') 
	
	| {TheNull} value=NULL
	|{ClassMemberDef} value=ClassMemberDefinition
	| {VariableDeclarationRef} value=VariableDeclarationRef
	
	;

DotValue:
	atom=Atomic  ((accesToList=AccessToList?) DOT dotPart=DotValue)?;

MapCreationPart:
	exprKey=Expression DOUBLE_QUOTE exprValue=Expression;

RelAttrubutesList:
	value+=Variable (',' value+=Variable)*;

VariableDeclaration:
	name=ValuableID ((DOUBLE_QUOTE type=TypeReference)?);


TypeReference:
	type=PrimitiveType | entityType=[ClassDefinition] ;




PrimitiveType:
	Text | Tuid | Pubkey | Name | Integer  | Boolean;

ValuableID:
	PrimitiveType | ID;



IntWithMinus:
	MinusChar? INT;

Name:
	'name';

Pubkey:
	'pubkey';

Timestamp:
	'timestamp';

Tuid:
	'tuid';

Boolean:
	'boolean';



Integer:
	'integer';

Text:
	'text';


Key:
	'key';

Index:
	'index';

Mutable:
	'mutable';

Var:
	'var';

Val:
	'val';



PlusChar:
	'+';

MinusChar:
	'-';

MulChar:
	'*';

DivChar:
	'/';



	
terminal ASSIGNMENT:'=';


terminal EQUALS:
	'==';



terminal DOUBLE_QUOTE:
	':';

terminal NULL:
	'null';
	
terminal DOT:'.';

terminal BYTE_ARRAY_CHAR:
	'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'A' | 'B' | 'C' | 'D'
	| 'E' | 'F';

terminal BYTE_ARRAY_PAIR:
	BYTE_ARRAY_CHAR BYTE_ARRAY_CHAR;

terminal BYTE_ARRAY_VALUE:
	'x' (('\'' BYTE_ARRAY_PAIR* '\'') | ('"' BYTE_ARRAY_PAIR* '"'));




/*
 * generated by Xtext 2.10.0
 */
package org.blockchain.rell.scoping

import java.util.List
import javax.inject.Inject
import org.blockchain.rell.rell.AttributeListField
import org.blockchain.rell.rell.ClassDefinition
import org.blockchain.rell.rell.ClassMemberDef
import org.blockchain.rell.rell.ClassMemberDefinition
import org.blockchain.rell.rell.CreateWhatPart
import org.blockchain.rell.rell.DotValue
import org.blockchain.rell.rell.Expression
import org.blockchain.rell.rell.JustNameDecl
import org.blockchain.rell.rell.Operation
import org.blockchain.rell.rell.TableNameWithAlias
import org.blockchain.rell.rell.Update
import org.blockchain.rell.rell.VariableDeclaration
import org.blockchain.rell.rell.VariableDeclarationRef
import org.blockchain.rell.typing.RellClassType
import org.blockchain.rell.typing.RellModelUtil
import org.blockchain.rell.typing.RellTypeProvider
import org.eclipse.emf.common.util.EList
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
import org.eclipse.xtext.EcoreUtil2
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.Scopes
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider

/**
 * This class contains custom scoping description.
 * 
 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping
 * on how and when to use it.
 */
class RellScopeProvider extends AbstractDeclarativeScopeProvider {

	@Inject extension RellTypeProvider
	
	
	def IScope getVariableDeclarationRefScope(VariableDeclarationRef variableDeclarationRef, EReference ref) {

		val container = variableDeclarationRef.eContainer;

		switch (container) {
			case (container instanceof VariableDeclarationRef): {

				if (container.eContainer instanceof DotValue) {
					val dotValue = container.eContainer as DotValue
					val parent = dotValue.eContainer

					switch (parent ) {
						
						case (parent.eContainer instanceof CreateWhatPart): {
							val scope = makeWhatPartVariableDeclarations(parent.eContainer)
							val operation = EcoreUtil2.getContainerOfType(variableDeclarationRef, Operation)
							if (operation !== null) {
								var operationVars = RellModelUtil.usedVariables(operation as Operation).filter [ variableInfo |
									variableInfo.declared
								].map[variableInfo|variableInfo.variableDeclaration]
								scope.addAll(operationVars)
							}
							return Scopes::scopeFor(scope)
						}
					}
				}
			}
			case (container instanceof ClassMemberDefinition): {

				val classMemberDefinition = container as ClassMemberDefinition;
				val classRef = classMemberDefinition.classRef;
				if (classRef !== null) {
					val varDeclList = classRef.getVarDeclList
					return Scopes::scopeFor(varDeclList)

				} else {
					val relContainer = variableDeclarationRef.relationalContainer
					switch (relContainer) {
						case (relContainer instanceof Update): {
							return (relContainer as Update).getVariableDeclarationRefScope
						}
					}
				}

			}
			case (container instanceof CreateWhatPart): {
				return Scopes::scopeFor(makeWhatPartVariableDeclarations(container))
			}
			
		}

		return super.getScope(variableDeclarationRef, ref)

	}

	protected def IScope variableDeclarationRefScope(VariableDeclarationRef variableDeclarationRef, EObject container,
		EReference ref) {
		switch (container) {
			
			case (container instanceof ClassMemberDefinition): {
				val notNotExprContainer = (container as ClassMemberDefinition).notClassMemberDefinition
				switch (notNotExprContainer) {
					
					case (notNotExprContainer instanceof DotValue): {

						val parentDotValue = notNotExprContainer as DotValue;
						val atom = parentDotValue.atom;

						switch (atom) {
							case (atom instanceof ClassMemberDefinition): {

								val classMemberDefinition = atom as ClassMemberDefinition;
								val variableDclarationRef = classMemberDefinition.variableDeclarationRef
								if (variableDclarationRef != null) {

									val typeFor = variableDclarationRef.typeFor
									// EcoreUtil2.getContainerOfType()
									if (typeFor instanceof RellClassType) {
										val variableDeclarationList = (typeFor as RellClassType).rellClassDefinition.
											attributeListField.makeVariableDeclarationList
										return Scopes::scopeFor(variableDeclarationList)
									}
								}

							}
						}
					}
				}

			}
			
			case (container instanceof Update): {
				val update = container as Update
				return Scopes::scopeFor(update.entity.makeVariableDeclarationList)
			}
			case (container instanceof CreateWhatPart): {
				return Scopes::scopeFor(container.makeWhatPartVariableDeclarations)

			}
			
			default: {
				val scope = super.getScope(variableDeclarationRef, ref)
				// println("scope"+scope.allElements)
				return scope;
			}
		}
		val scope = super.getScope(variableDeclarationRef, ref)
		return scope;
	}

	protected def List<VariableDeclaration> makeWhatPartVariableDeclarations(EObject container) {
		var ClassDefinition en;
		switch (container.eContainer) {
			case container.eContainer instanceof Update: {
				en = (container.eContainer as Update).entity.getClassDefinitionByTableNameWithAlias
			}
			
		}

		return en.attributeListField.makeVariableDeclarationList

	}

	protected def List<VariableDeclaration> makeVariableDeclarationList(EList<AttributeListField> attrubuteListField) {
		val List<VariableDeclaration> variableDeclarationList = newArrayList;
		attrubuteListField.forEach [ x |
			if (x.attributeList !== null) {
				x.attributeList.forEach [ attrList |
					if (attrList !== null && attrList.value !== null) {
						attrList.value.forEach [ variable |
							{
								if (variable !== null) {
									variableDeclarationList.add(variable.name)
								}
							}
						]
					}
				]
			}
		]
		variableDeclarationList
	}

	protected def getClassDefinitionByTableNameWithAlias(TableNameWithAlias tableNameWithAlias) {
			switch (tableNameWithAlias) {
			case (tableNameWithAlias.classRefDecl!==null): {
				return (tableNameWithAlias.classRefDecl).classDef
			}
			case (tableNameWithAlias.justNameDecl!==null): {
				return (tableNameWithAlias as JustNameDecl).name
			}
		}
	}

	protected def List<VariableDeclaration> makeVariableDeclarationList(TableNameWithAlias tableNameWithAlias) {
		val attributeListField = tableNameWithAlias.getClassDefinitionByTableNameWithAlias.attributeListField
		
		val List<VariableDeclaration> variableDeclarationList = newArrayList;
		attributeListField.forEach [ x |
			if (x.attributeList !== null) {
				x.attributeList.forEach [ attrList |
					if (attrList !== null && attrList.value !== null) {
						attrList.value.forEach [ variable |
							{
								if (variable !== null) {
									variableDeclarationList.add(variable.name)
								}
							}
						]
					}
				]
			}
		]
		variableDeclarationList
	}



	def IScope getClassMemberDefinition(ClassMemberDefinition classMemberDefinition, EObject processedObject,
		EReference ref) {
		val notExprConst = classMemberDefinition.eContainer.notExressionContainer

		switch (notExprConst) {
			case (notExprConst instanceof Update): {

				return (notExprConst as Update).getClassMemberDefScope;
			}
			
		}
		return super.getScope(processedObject, ref);
	}

	
	def getClassMemberDefScope(Update update) {
		val List<TableNameWithAlias> classDefList = newArrayList
		classDefList.add(update.entity)
		return Scopes::scopeFor(classDefList);
	}

	
	/**
	 * Return the variable declaration names scope for Update
	 */
	def getVariableDeclarationRefScope(Update update) {
		val List<VariableDeclaration> classDefList = makeVariableDeclarationList(update.entity.getClassDefinitionByTableNameWithAlias.attributeListField)

		return Scopes::scopeFor(classDefList);
	}

	def getVarDeclList(TableNameWithAlias tableNameWithAlias) {

		var EList<AttributeListField> attrubuteListField = tableNameWithAlias.getClassDefinitionByTableNameWithAlias.attributeListField
		if (attrubuteListField === null) {
			return newArrayList
		}
		return makeVariableDeclarationList(attrubuteListField);
	}

	def notExressionContainer(EObject context) {
		var privateContainer = context
		while (privateContainer instanceof Expression) {
			privateContainer = privateContainer.eContainer
		}
		return privateContainer;
	}

	def relationalContainer(EObject context) {
		var privateContainer = context
		while (!(privateContainer instanceof Update)) {
			privateContainer = privateContainer.eContainer
		}
		return privateContainer;
	}

	def notClassMemberDefinition(EObject context) {
		var privateContainer = context
		while (privateContainer instanceof ClassMemberDefinition) {
			privateContainer = privateContainer.eContainer
		}
		return privateContainer;
	}

	override IScope getScope(EObject context, EReference reference) {
		switch (context) {
			case (context === null):
				return IScope.NULLSCOPE
			case (context instanceof VariableDeclarationRef): {
				return getVariableDeclarationRefScope(context as VariableDeclarationRef, reference);
			}

		}
		return super.getScope(context, reference);

	}

}




Re: Null properties of the EObject in the ScopeProvider [message #1804008 is a reply to message #1804006] Fri, 15 March 2019 13:00 Go to previous messageGo to next message
Karsten Thoms is currently offline Karsten ThomsFriend
Messages: 687
Registered: July 2009
Location: Dortmund, Germany
Senior Member

Quote:
it means, that in the following rule classRef equals to null.


No, it means that getClassDefinitionByTableNameWithAlias returns null. Which is likely because you access ClassRefDecl#classDef there. This again is a cross reference, which may be unresolved yet and thus be a proxy.

As a rule of thumb, never try to navigate a cross reference during scoping. You may end in trouble like that or in cyclic resolution problems. Be aware of proxies and don't try to resolve them, that's again up to the LinkingService.
Re: Null properties of the EObject in the ScopeProvider [message #1804018 is a reply to message #1804008] Fri, 15 March 2019 20:47 Go to previous messageGo to next message
kozhaev Vladimir is currently offline kozhaev VladimirFriend
Messages: 108
Registered: July 2009
Senior Member
Well, it's because of both of fields of TableNameWithAlias equals to null

protected def getClassDefinitionByTableNameWithAlias(TableNameWithAlias tableNameWithAlias) {
			switch (tableNameWithAlias) {
			case (tableNameWithAlias.classRefDecl!==null): {
				return (tableNameWithAlias.classRefDecl).classDef
			}
			case (tableNameWithAlias.justNameDecl!==null): {
				return (tableNameWithAlias as JustNameDecl).name
			}
		}
	}

What I can to do to solve this problem?

May I ask you to tell me in details about the following Quote:
You may end in trouble like that or in cyclic resolution problems. Be aware of proxies and don't try to resolve them, that's again up to the LinkingService.

Or give the link?
Re: Null properties of the EObject in the ScopeProvider [message #1804020 is a reply to message #1804018] Fri, 15 March 2019 21:47 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13062
Registered: July 2009
Senior Member
Is tableNameWithAlias a proxy that cannot be resolved ?

Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Null properties of the EObject in the ScopeProvider [message #1804021 is a reply to message #1804020] Fri, 15 March 2019 22:05 Go to previous messageGo to next message
kozhaev Vladimir is currently offline kozhaev VladimirFriend
Messages: 108
Registered: July 2009
Senior Member
I'm not sure what is a proxy in this context. Problem is fields of TableNameWithAlias are null both, but in my picture of the world only one field can be equals to null
Re: Null properties of the EObject in the ScopeProvider [message #1804035 is a reply to message #1804021] Sat, 16 March 2019 11:18 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13062
Registered: July 2009
Senior Member
is you debug on the TableNameWithAlias how does it look like in the debug view.
and is it on a declared place or a referenced place. i have understood its on a referenced place


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Null properties of the EObject in the ScopeProvider [message #1804036 is a reply to message #1804035] Sat, 16 March 2019 11:36 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13062
Registered: July 2009
Senior Member
=> having a unit test would really help

Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Null properties of the EObject in the ScopeProvider [message #1804045 is a reply to message #1804036] Sat, 16 March 2019 19:15 Go to previous messageGo to next message
kozhaev Vladimir is currently offline kozhaev VladimirFriend
Messages: 108
Registered: July 2009
Senior Member
Quote:
is you debug on the TableNameWithAlias how does it look like in the debug view.
and is it on a declared place or a referenced place. i have understood its on a referenced place

Please, see on the picture below(unfortunately have some problem with expressions view on linux)
https://c.radikal.ru/c24/1903/0a/2649da3e2351.jpg
Quote:
=> having a unit test would really help


Do you mean the ScopeProvider testing? Really, this text is part of the unittest

Re: Null properties of the EObject in the ScopeProvider [message #1804046 is a reply to message #1804045] Sat, 16 March 2019 20:04 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13062
Registered: July 2009
Senior Member
i want to see the object in the variables view

Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Null properties of the EObject in the ScopeProvider [message #1804047 is a reply to message #1804046] Sat, 16 March 2019 20:05 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13062
Registered: July 2009
Senior Member
and i mean: you did not provide a unit test that reproduces the problem.

Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Null properties of the EObject in the ScopeProvider [message #1804048 is a reply to message #1804047] Sat, 16 March 2019 20:08 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13062
Registered: July 2009
Senior Member
i also wonder how you circumvented the ambiguities in your grammar.

Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Null properties of the EObject in the ScopeProvider [message #1804049 is a reply to message #1804048] Sat, 16 March 2019 20:21 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13062
Registered: July 2009
Senior Member
println(tableNameWithAlias.eIsProxy) gives true when activating backtracking to tackle ambiguity.
TableNameWithAlias itself has no name.
TableNameWithAlias:
classRefDecl=ClassRefDecl |
justNameDecl=JustNameDecl;

so you have to implement a name provider

public class MyDslQualifiedNameProvider extends DefaultDeclarativeQualifiedNameProvider {
	
	public QualifiedName qualifiedName(TableNameWithAlias t) {
		QualifiedName result = null;
		if (t.getClassRefDecl() != null) {
			if (t.getClassRefDecl().getName() != null) {
				result = getConverter().toQualifiedName(t.getClassRefDecl().getName());
			}
		}
		if (t.getJustNameDecl() != null) {
			List<INode> nodes = NodeModelUtils.findNodesForFeature(t.getJustNameDecl(), MyDslPackage.Literals.JUST_NAME_DECL__NAME);
			if (!nodes.isEmpty()) {
				result = getConverter().toQualifiedName(nodes.get(0).getText());
			}
		}
		return result;
	}

}


then this code makes no sense. it will lead to classcast
	protected def getClassDefinitionByTableNameWithAlias(TableNameWithAlias tableNameWithAlias) {
			switch (tableNameWithAlias) {
			case (tableNameWithAlias.classRefDecl!==null): {
				return (tableNameWithAlias.classRefDecl).classDef
			}
			case (tableNameWithAlias.justNameDecl!==null): {
				return (tableNameWithAlias as JustNameDecl).name
			}
		}
	}


maybe you mean


case (tableNameWithAlias.justNameDecl!==null): {
				return tableNameWithAlias.justNameDecl.name
			}




Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Null properties of the EObject in the ScopeProvider [message #1804050 is a reply to message #1804048] Sat, 16 March 2019 20:25 Go to previous messageGo to next message
kozhaev Vladimir is currently offline kozhaev VladimirFriend
Messages: 108
Registered: July 2009
Senior Member
Quote:
i want to see the object in the variables view

Sure, please see the picture below.
https://d.radikal.ru/d39/1903/77/2bb3af71fd42.png

Quote:
and i mean: you did not provide a unit test that reproduces the problem.

I'm not sure how to implement the UnitTest to reproduce the problem with null pointer exception.
This is the text what not works. I have null pointer exception during execution of this test.
@Test
	def void testUpdateOperationFullAccess() {
		assertParsingTrue('''
			class foo { key k: integer; mutable name; }
			operation op() {
			    update foo @{foo.k == 122}(name = "new_name");    
			}
		''')
	}
........
def void assertParsingTrue(String codeSnippet) {
		val result = parseHelper.parse(codeSnippet)
		Assert.assertNotNull(result);
		Assert.assertNotNull(result.eResource)
		Assert.assertNotNull(result.eResource.errors)
		val errors = result.eResource.errors

		Assert.assertTrue( '''Unexpected errors: «errors.join(", ")»''', errors.empty)

		result.assertNoErrors
	}


Quote:

i also wonder how you circumvented the ambiguities in your grammar.


Also not sure what do you mean. Grammar Is working on numbers of tests. This is a full version of the project what I'm working now






Re: Null properties of the EObject in the ScopeProvider [message #1804052 is a reply to message #1804050] Sat, 16 March 2019 20:27 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13062
Registered: July 2009
Senior Member
see my answer before.
i dont see any nameprovider binding here https://github.com/vladimirkozhaev/blockchainlanugage/blob/master/org.blockchain.rell/src/org/blockchain/rell/RellRuntimeModule.xtend

and with ambiguities i mean this:
https://github.com/vladimirkozhaev/blockchainlanugage/blob/0df6b479af7887441006a8fa6ed6b0a5fa5fc0b4/org.blockchain.rell/src/org/blockchain/rell/GenerateRell.mwe2#L45


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Sat, 16 March 2019 20:29]

Report message to a moderator

Re: Null properties of the EObject in the ScopeProvider [message #1804053 is a reply to message #1804052] Sat, 16 March 2019 20:52 Go to previous messageGo to next message
kozhaev Vladimir is currently offline kozhaev VladimirFriend
Messages: 108
Registered: July 2009
Senior Member
Hmm... So look like I need to read about the RuntimeModule first, then get back to this problem. Isn't it?
Re: Null properties of the EObject in the ScopeProvider [message #1804054 is a reply to message #1804053] Sat, 16 March 2019 20:57 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13062
Registered: July 2009
Senior Member
no

the problem is that you dont have a name provider.
see my example above

here is how a binding could look like

class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {

override bindIQualifiedNameProvider() {
MyDslQualifiedNameProvider
}

}


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Null properties of the EObject in the ScopeProvider [message #1805469 is a reply to message #1804054] Mon, 15 April 2019 16:40 Go to previous message
kozhaev Vladimir is currently offline kozhaev VladimirFriend
Messages: 108
Registered: July 2009
Senior Member
I have already implemented it, but some time name provider is not worked(Please, see my updated grammar bellow)

Consider this code

Quote:

class user { firstName: text;}
query q1() { val t = user @ { .firstName == 'Bill' }; return t.firstName; }


I have the null pointer exception

And as I debug, it's happends because the "TableNameWithAlias" in this place has both fields equals to null

So this method return null

protected def getClassDefinitionByTableNameWithAlias(TableNameWithAlias tableNameWithAlias) {
		switch (tableNameWithAlias) {
			case (tableNameWithAlias.classRefDecl !== null): {
				return (tableNameWithAlias.classRefDecl).classDef
			}
			case (tableNameWithAlias.justNameDecl !== null): {
				return tableNameWithAlias.justNameDecl.name
			}
		}
	}


And I can't add to the scope field of the "t" i.e. t.firstName
I believe it's because compiler really doesn't know the type of t. Is it true? If yes, probably I need to add the type inference and get the type of t from it. So, may I ask you to give me the best architecture of this functionality?

Quote:


org.eclipse.emf.common.util.WrappedException: java.lang.NullPointerException
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:244)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.doResolveLazyCrossReference(LazyLinkingResource.java:203)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.resolveLazyCrossReference(LazyLinkingResource.java:162)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.resolveLazyCrossReferences(LazyLinkingResource.java:148)
at org.eclipse.xtext.EcoreUtil2.resolveLazyCrossReferences(EcoreUtil2.java:500)
at org.eclipse.xtext.validation.ResourceValidatorImpl.resolveProxies(ResourceValidatorImpl.java:161)
at org.eclipse.xtext.validation.ResourceValidatorImpl.validate(ResourceValidatorImpl.java:74)
at org.eclipse.xtext.testing.validation.ValidationTestHelper.validate(ValidationTestHelper.java:168)
at org.eclipse.xtext.testing.validation.ValidationTestHelper.assertNoErrors(ValidationTestHelper.java:178)
at org.eclipse.xtext.testing.validation.ValidationTestHelper.assertNoErrors(ValidationTestHelper.java:92)
at org.blockchain.rell.tests.WorkingTests.assertParsingTrue(WorkingTests.java:2210)
at org.blockchain.rell.tests.WorkingTests.testBuilkAssignOperatorInWhatPartMin(WorkingTests.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.eclipse.xtext.testing.XtextRunner$1.evaluate(XtextRunner.java:49)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
Caused by: java.lang.NullPointerException
at org.blockchain.rell.scoping.RellScopeProvider.getVarDeclList(RellScopeProvider.java:430)
at org.blockchain.rell.scoping.RellScopeProvider.getVariableDeclarationRefScope(RellScopeProvider.java:136)
at org.blockchain.rell.scoping.RellScopeProvider.getScope(RellScopeProvider.java:528)
at org.eclipse.xtext.linking.impl.DefaultLinkingService.getScope(DefaultLinkingService.java:58)
at org.eclipse.xtext.linking.impl.DefaultLinkingService.getLinkedObjects(DefaultLinkingService.java:107)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:265)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:236)
... 35 more





grammar org.blockchain.rell.Rell with org.eclipse.xtext.common.Terminals

generate rell "http://www.blockchain.org/rell/Rell"

Model:
	entities+=ClassDefinition*
	operations+=(Operation | Query | Function)*;

ClassDefinition:
	('class' | 'record' | 'object') name=ID ('extends' superType=[ClassDefinition])? LEFT_BRACE
	attributeListField+=AttributeListField*
	RIGHT_BRACE;

AttributeListField:
	mutable=Mutable? key=Key? index=Index? attributeList+=RelAttrubutesList ';';

Operation:
	"operation" name=ID LEFT_BRACKET parameters=RelAttrubutesList? RIGHT_BRACKET LEFT_BRACE statements+=Statement*
	('return'
	returnExr=Expression ';')? RIGHT_BRACE;

Query:
	"query" name=ID LEFT_BRACKET parameters=RelAttrubutesList? RIGHT_BRACKET
	(DOUBLE_QUOTE type=TypeReference)?
	((ASSIGNMENT returnExr=Expression ';') |
	(LEFT_BRACE
	statements+=Statement*
	(('return' returnExr=Expression ';')?)
	RIGHT_BRACE));

Function:
	"function" name=ID LEFT_BRACKET parameters=RelAttrubutesList? RIGHT_BRACKET
	(DOUBLE_QUOTE type=TypeReference QuestionChar?)?
	((ASSIGNMENT returnExr=Expression ';') |
	(LEFT_BRACE
	statements+=Statement*
	(('return' returnExr=Expression ';')?)
	RIGHT_BRACE));

Statement:
	(relation=Relational | variable=OperationVariable | varInitiation=VarInitiation | methodCall=DotValue) ';';

VarInitiation:
	name=Expression ASSIGNMENT
	expression=Expression;

OperationVariable:
	assessModificator=(Var | Val) variable=Variable;

Variable:
	name=VariableDeclaration ((ASSIGNMENT expression=Expression)?);

Relational:
	AtOperator | Update | Delete | Create;

Update:
	'update' (tableNameWithAlias+=TableNameWithAlias | LEFT_BRACKET tableNameWithAlias+=TableNameWithAlias (','
	tableNameWithAlias+=TableNameWithAlias)* RIGHT_BRACKET) ((Ampersand LEFT_BRACE ((conditions+=Expression (','
	conditions+=Expression)*)?) RIGHT_BRACE)?) LEFT_BRACKET
	createWhatPart+=CreateWhatPart (','
	createWhatPart+=CreateWhatPart)*
	RIGHT_BRACKET;

Delete:
	'delete' (tableNameWithAlias+=TableNameWithAlias | LEFT_BRACKET tableNameWithAlias+=TableNameWithAlias (','
	tableNameWithAlias+=TableNameWithAlias)* RIGHT_BRACKET) Ampersand LEFT_BRACE conditions+=Expression (','
	conditions+=Expression)* RIGHT_BRACE;

Create:
	'create' (tableNameWithAlias+=TableNameWithAlias | LEFT_BRACKET tableNameWithAlias+=TableNameWithAlias (','
	tableNameWithAlias+=TableNameWithAlias)* RIGHT_BRACKET) LEFT_BRACKET (createWhatPart+=CreateWhatPart (','
	createWhatPart+=CreateWhatPart)*)? RIGHT_BRACKET;

	//There are problem with record part. So will check it in the validatiie
CreateClassPart:
	(entity=[ClassDefinition]) LEFT_BRACKET (createWhatPart+=CreateWhatPart (','
	createWhatPart+=CreateWhatPart)*)? RIGHT_BRACKET;

CreateWhatPart:
	(ASSIGNMENT? DOT? varDeclRef=VariableDeclarationRef (ASSIGNMENT | PLUS_ASSGIN | MINUS_ASSGIN | DIV_ASSGIN |
	MUL_ASSGIN))?
	condition+=Expression;

AtOperator:
	(tableNameWithAlias+=TableNameWithAlias |
	(LEFT_BRACKET
	tableNameWithAlias+=TableNameWithAlias (',' tableNameWithAlias+=TableNameWithAlias)*
	RIGHT_BRACKET))
	Ampersand
	(ampersandModificator=AmpersandModificator?)
	LEFT_BRACE
	(ASSIGNMENT? conditions+=Expression (',' ASSIGNMENT? conditions+=Expression)*)?
	RIGHT_BRACE
	(tupleValue=TupleValue?);

TupleValue:
	LEFT_BRACKET members+=TupleValueMember (',' tuplePart+=TupleValueMember)* RIGHT_BRACKET;

ListCreation:
	LEFT_SQUARE_BRACE arguments=Arguments RIGHT_SQUARE_BRACE (DOT EMBEDDED_METHOD
	listMethodArguments+=ArgumentsInBrackets)*;

MapCreation:
	LEFT_SQUARE_BRACE mapPart+=MapCreationPart (',' mapPart+=MapCreationPart)* RIGHT_SQUARE_BRACE;

TupleValueMember:
	(name=ValuableID ASSIGNMENT)? value=Expression;

ClassMemberDefinition:
	(classRef=[TableNameWithAlias])? DOT (variableDeclarationRef=VariableDeclarationRef);

TableNameWithAlias:
	classRefDecl=ClassRefDecl |
	justNameDecl=JustNameDecl;

ClassRefDecl:
	name=ID DOUBLE_QUOTE classDef=[ClassDefinition];

JustNameDecl:
	name=[ClassDefinition];

VariableDeclarationRef:
	name=[VariableDeclaration|ValuableID];

MethodCall:
	name=MethodName ((listSpec=ListSpecification | mapSpec=MapSpecification)?) arguments=ArgumentsInBrackets;

OperationQueryOFunctionCall:
	(name=[Query] | name=[Operation] | name=[Function]) arguments=ArgumentsInBrackets;

Arguments:
	listPart+=Expression (',' listPart+=Expression)*;

ArgumentsInBrackets:
	LEFT_BRACKET arguments=Arguments? RIGHT_BRACKET;

MethodName:
	EMBEDDED_METHOD;

AccessToList:
	LEFT_SQUARE_BRACE expr=Expression RIGHT_SQUARE_BRACE;

Expression:
	or=Or;

Or returns Expression:
	And ({Or.left=current} "or" right=And)*;

And returns Expression:
	Equality ({And.left=current} "and" right=Equality)*;

Equality returns Expression:
	Comparison ({Equality.left=current} op=(EQUALS | NOT_EQUALS | EQUALSS | NOT_EQUALSS)
	right=Comparison)*;

Comparison returns Expression:
	PlusOrMinus ({Comparison.left=current} op=(MORE_EQUAL | LESS_EQUAL | MORE | LESS | IN)
	right=PlusOrMinus)*;

PlusOrMinus returns Expression:
	MulOrDiv (({Plus.left=current} PlusChar | {Minus.left=current} MinusChar)
	right=MulOrDiv)*;

MulOrDiv returns Expression:
	Primary ({MulOrDiv.left=current} op=(MulChar | DivChar | Percent)
	right=Primary)*;

Primary returns Expression:
	DotValue;

UnaryOperation:
	prefixChar=(PlusChar | MinusChar | MulChar | DivChar | NOT) expression=Primary;

ExprInBrackets:
	(LEFT_BRACKET expr=Expression RIGHT_BRACKET);

DotValue:
	atom=Atomic (accesToList=AccessToList?) ((DOT dotPart=DotValue)?);

Atomic returns Expression:
	{ExprInBrackets} value=ExprInBrackets
	| {UnaryOperation} value=UnaryOperation
	| {IntConstant} value=IntWithMinus
	| {StringConstant} value=STRING |
	{ByteArrayConstant} value=BYTE_ARRAY_VALUE |
	{BoolConstant} value=('true' | 'false') |
	{SelectOp} value=AtOperator |
	{CreateAtom} value=Create
	| {TupleRes} value=TupleValue
	| {ListCreation} value=ListCreation
	| {MapCreation} value=MapCreation
	| {TheNull} value=NULL
	| {OneParamMethodCall} value=OneParamMethodCall
	| {TwoParamsMethodCall} value=TwoParamsMethodCall
	| {MultiParamsMethodCall} value=MultiParamsMethodCall
	| {MethodCall} value=MethodCall
	| {OperationQueryOFunctionCall} value=OperationQueryOFunctionCall
	| {CreateClassPart} value=CreateClassPart
	| {ClassMemberDef} value=ClassMemberDefinition
	| {VariableDeclarationRef} value=VariableDeclarationRef;

MapCreationPart:
	exprKey=Expression DOUBLE_QUOTE exprValue=Expression;

RelAttrubutesList:
	value+=Variable (',' value+=Variable)*;

VariableDeclaration:
	name=ValuableID ((DOUBLE_QUOTE type=TypeReference)?);

TupleVarDeclaration:
	(name=ValuableID DOUBLE_QUOTE)? type=TypeReference;

TypeReference:
	type=PrimitiveType | entityType=[ClassDefinition] | tuple=TupleType | list=ListType | set=SetType | map=MapType;

ListType:
	List ListSpecification;

SetType:
	Set ListSpecification;

MapType:
	Map MapSpecification;

ListSpecification:
	LESS listType=TypeReference (QuestionChar?) MORE (QuestionChar?);

MapSpecification:
	LESS keySpec=TypeReference (QuestionChar?) ',' valSpec=TypeReference (QuestionChar?) MORE;

TupleType:
	LEFT_BRACKET varDecl+=TupleVarDeclaration (QuestionChar?) (',' varDecl+=TupleVarDeclaration (QuestionChar?))*
	RIGHT_BRACKET;

OneParamMethodCall:
	methodName=ONE_PARAM_METHOD LEFT_BRACKET arg=Expression RIGHT_BRACKET;

TwoParamsMethodCall:
	methodName=TWO_PARAMS_METHOD LEFT_BRACKET arg1=Expression ',' arg2=Expression RIGHT_BRACKET;

MultiParamsMethodCall:
	methodName=MULTI_PARAMS_METHOD args=ArgumentsInBrackets;

PrimitiveType:
	Text | Tuid | Pubkey | Name | Timestamp | Integer | Json | ByteArray | Boolean;

ValuableID:
	PrimitiveType | ID;

AmpersandModificator:
	PlusChar | MulChar | QuestionChar;

IntWithMinus:
	MinusChar? INT;

Name:
	'name';

Pubkey:
	'pubkey';

Timestamp:
	'timestamp';

Tuid:
	'tuid';

Boolean:
	'boolean';

Json:
	'json';

Integer:
	'integer';

Text:
	'text';

ByteArray:
	'byte_array';

List:
	'list';

Map:
	'map';

Set:
	'set';

Key:
	'key';

Index:
	'index';

Mutable:
	'mutable';

Var:
	'var';

Val:
	'val';

Ampersand:
	'@';

QuestionChar:
	'?';

PlusChar:
	'+';

MinusChar:
	'-';

MulChar:
	'*';

DivChar:
	'/';

Percent:
	'%';

EMBEDDED_METHOD:
	"add" | "addAll" | "contains" | "containsAll" | "removeAll" | "calculate" | "sub" | "size" |
	"removeAt" | "clear" | "requireNotEmpty" | "upperCase" | "lowerCase" | "_map" | "map" | "_list" | "list" | "set" |
	"_set" | "empty" | "get" |
	"str" | "put" | "putAll" | "remove" | "keys" | "values";

ONE_PARAM_METHOD:
	'abs' | 'is_signer' | 'json';

TWO_PARAMS_METHOD:
	'max' | 'min';

MULTI_PARAMS_METHOD:
	'log' | 'print';

terminal IN:
	'in';

terminal RIGHT_SQUARE_BRACE:
	']';

terminal LEFT_SQUARE_BRACE:
	'[';

terminal RIGHT_BRACE:
	'}';

terminal LEFT_BRACE:
	'{';

terminal RIGHT_BRACKET:
	')';

terminal LEFT_BRACKET:
	'(';

terminal NOT:
	'not';

terminal ASSIGNMENT:
	'=';

terminal DIV_ASSGIN:
	'/=';

terminal MUL_ASSGIN:
	'*=';

terminal PLUS_ASSGIN:
	'+=';

terminal MINUS_ASSGIN:
	'-=';

terminal EQUALS:
	'==';

terminal EQUALSS:
	'===';

terminal NOT_EQUALS:
	'!=';

terminal NOT_EQUALSS:
	'!==';

terminal MORE_EQUAL:
	'>=';

terminal LESS_EQUAL:
	'<=';

terminal MORE:
	'>';

terminal LESS:
	'<';

terminal DOUBLE_QUOTE:
	':';

terminal NULL:
	'null';

terminal DOT:
	'.';

terminal BYTE_ARRAY_CHAR:
	'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'A' | 'B' | 'C' | 'D'
	| 'E' | 'F';

terminal BYTE_ARRAY_PAIR:
	BYTE_ARRAY_CHAR BYTE_ARRAY_CHAR;

terminal BYTE_ARRAY_VALUE:
	'x' (('\'' BYTE_ARRAY_PAIR* '\'') | ('"' BYTE_ARRAY_PAIR* '"'));



Previous Topic:Generating duplicate method bodies in AbstractModelInferrer
Next Topic:parsing issue affecting content assist
Goto Forum:
  


Current Time: Sun Aug 18 10:48:08 GMT 2019

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

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

Back to the top