got "Cyclic resolution of lazy links" when nested object access parent object [message #1690924] |
Wed, 01 April 2015 01:07 |
Bob Tao Messages: 23 Registered: March 2015 |
Junior Member |
|
|
I got "Cyclic resolution of lazy links" when nested object access parent object .I try to solve this problem many days.
I have a grammar,like this:
grammar com.huawei.cs.ucl.Ucl with org.eclipse.xtext.common.Terminals
generate ucl "this is a url"
UclProgram:
(package=PackageDeclaration)?
(imports+=ImportDeclaration)*
(classes+=UclClass)*
(instances+=UclInstance)*
;
ModuleDeclaration:
'module' name= QualifiedName id=INT
;
PackageDeclaration:
'package' name = [ModuleDeclaration | QualifiedName]
;
ImportDeclaration:
'import' importedNamespace = QualifiedName | importedNamespace= QualifiedNameWithWildcard
;
QualifiedName:
ID ('.' ID)*
;
QualifiedNameWithWildcard:
QualifiedName ('.*')?
;
UclClass:
'class' name=ID
'{'
(members+=UclClassMember)*
'}';
UclClassMember:
UclClassField
;
UclClassField:
type=[UclClass] name=ID ('[' minSize=INT ',' maxSize=ArrayUpperLimit ']')? ';'
;
ArrayUpperLimit:
INT | '*'
;
UclInstance:
clazz=[UclClass] name=ID
'{'
(attributes+=UclInstanceAttribute)*
'}'
;
UclInstanceAttribute:
iafield=[UclClassField] iavalue=UclInstanceAttributeValue
;
UclInstanceAttributeValue:
UclBasicValue | UclObjectValue | UclArrayValue
;
UclBasicValue:
':' value=UclValueObject ';'
;
UclObjectValue:
'{'
(attributes+=UclInstanceAttribute)*
'}'
;
UclValueObject:
INT | STRING
;
UclArrayValue:
'['
(elements+=UclArrayElement (',' elements+=UclArrayElement)*)?
']'
;
UclArrayElement:
INT | STRING |UclObjectValue
;
I found, if a feature is a cross reference, I will got a exception when I call the cross reference object 's member.
whatever I modify the grammar, I can't avoid this exception.
org.eclipse.xtext.linking.lazy.LazyLinkingResource$CyclicLinkingException: Cyclic resolution of lazy links : UclInstanceAttribute.iafield->UclInstanceAttribute.iafield in resource 'platform:/resource/project3/src/file3.ucl'.
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.handleCyclicResolution(LazyLinkingResource.java:303)
org.eclipse.xtext.linking.lazy.LazyLinkingResource$CyclicLinkingException: Cyclic resolution of lazy links : UclInstanceAttribute.iafield->UclInstanceAttribute.iafield in resource 'platform:/resource/project3/src/file3.ucl'.
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.handleCyclicResolution(LazyLinkingResource.java:303)
this is my dsl example :
class string{}
class int{}
class javascript{}
class Product
{
int prodID;
string prodName;
string attributes[0,10];
Price prices[0,*];
}
class Price
{
int priceID;
int amount;
}
class Customer
{
int id;
string name;
Product offer;
javascript init;
}
Customer cust
{
id:123;
name:'cust1';
offer {
prodID:23;
prodName:"prod1";
prices[
Price price1{
....
}
Price price2{
....
}
]
}
}
public IScope scope_UclInstanceAttribute_iafield(
UclInstanceAttribute parentAttribute, EReference reference) {
System.out.println("scope_UclInstanceAttribute_iafield:"
+ parentAttribute.toString());
ArrayList<UclClassField> fields = new ArrayList<UclClassField>();
if (parentAttribute.getIafield()!=null) {
StringBuffer sb=new StringBuffer();
sb.append(parentAttribute.getIafield().eCrossReferences().toString());
System.out.println(sb);
UclClass clazz = (UclClass) parentAttribute.getIafield().getType();
EList<UclClassMember> members = clazz.getMembers();
for (UclClassMember member : members) {
if (member instanceof UclClassField) {
UclClassField field = (UclClassField) member;
fields.add(field);
}
}
}
return Scopes.scopeFor(fields);
}
I have to access the class member's type to support content assistant and link.
For example I have to get offer class type and members inside offer instance.
I guess I could use different method to access context and get the class type.
could you help me solve this problem?
thanks!
[Updated on: Wed, 01 April 2015 01:33] Report message to a moderator
|
|
|
Re: got "Cyclic resolution of lazy links" when nested object access parent object [message #1690945 is a reply to message #1690924] |
Wed, 01 April 2015 08:16 |
|
Hi,
recursive scoping does not work with xtext. the following example works for me, maybe you can adapt it to your needs
Model:
entities+=Entity*
instances+=ClassInstance*;
Entity:
"entity" name=ID "{"
fields+=Field*
"}";
Field:
Attribute | Reference;
Attribute:
"attr" name=ID ":" simpleType=SimpleType;
Reference:
"ref" name=ID ":" entityType=[Entity];
enum SimpleType:
string | int | boolean;
ClassInstance:
name=ID type=[Entity]
'{'
value+=AttributeInstance*
'}';
AttributeInstance:
fieldReference=[Field]
(expressions+=InstanceExpression
| '[' expressions+=InstanceExpression (',' expressions+=InstanceExpression)* ']');
InstanceExpression:
Literal
| AttributeInstanceExpression;
AttributeInstanceExpression:
{AttributeInstanceExpression}
'{'
values+=AttributeInstance*
'}';
Literal:
StringLiteral
| NumberLiteral
| BooleanLiteral;
StringLiteral:
value=STRING;
NumberLiteral:
value=INT;
BooleanLiteral:
{BoolescherAusdruck} ((value?="true") | "false");
class MyDslScopeProvider extends AbstractDeclarativeScopeProvider {
def public IScope scope_AttributeInstance_fieldReference(AttributeInstance inst, EReference ref) {
var EObject container = inst.eContainer();
if (container instanceof ClassInstance) {
return scope_AttributeInstance_fieldReference(container as ClassInstance, ref);
} else if (container instanceof AttributeInstanceExpression) {
return scope_AttributeInstance_fieldReference(container as AttributeInstanceExpression, ref);
}
return IScope.NULLSCOPE;
}
def public IScope scope_AttributeInstance_fieldReference(AttributeInstanceExpression expr, EReference ref) {
val field = (expr.eContainer() as AttributeInstance).fieldReference;
if (field instanceof Reference) {
return Scopes.scopeFor(field.entityType.fields)
}
return IScope.NULLSCOPE;
}
def public IScope scope_AttributeInstance_fieldReference(ClassInstance cls, EReference ref) {
return Scopes.scopeFor(cls.type.fields);
}
}
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.05507 seconds