Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Duplicate entries / namespace problems
Duplicate entries / namespace problems [message #870248] Mon, 07 May 2012 12:47 Go to next message
Heinrich Müller is currently offline Heinrich Müller
Messages: 10
Registered: March 2012
Junior Member
Hi guys,
i have this grammar:

grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals

generate myDsl "http ://www.xtext.org/example/mydsl/MyDsl"

Model:
	(jobfunction += JobFunction)*
;
	


JobFunction: name='executeJob'
			'('  ')''{'
			(statements+=Statement)*
			'}'
;

Statement : 
		TryStatement       |
		CatchStatement     |
		DeclarationStatement 
;

enum CatchEnums: NegativeResponseException | NoResponseException 
;

TryStatement       : keyword='try' '{'(tryStatements+=Statement)+ '}' ;
CatchStatement     : keyword='catch' ((exception=CatchEnums | userException=StringDeclaration) '{'(catchStatements+=Statement)+ '}') ;

DeclarationStatement : Declaration ';'
;


Declaration : StringNumberBoolDeclaration |
			  ButtonDeclaration;
			  
StringNumberBoolDeclaration : StringDeclaration | IntDeclaration | FloatDeclaration | BoolDeclaration;
StringDeclaration : type='string' name=ID ('=' exp=Expression)?;
IntDeclaration : type='int' name=ID ('=' exp=Expression)?;
FloatDeclaration : type='float' name=ID ('=' exp=Expression)?;
BoolDeclaration: type='bool' name=ID ('=' exp=Expression)?;
ButtonDeclaration : type='button' name=ID;

Expression : expSingle+=SingleExpression (op+=Operator expSingle+=SingleExpression)*
;

enum Operator : PLUS='+' |
				MINUS='-' |
				EQUAL='==' |
				NOT='!'
;

SingleExpression :     
				( litInt = INT ) |
				( litBool = ('true' | 'false') ) |
				( invert='!'? var = [Declaration] )
;


with this simple file:

executeJob () 
{
	try
	{
		int bla;	 
	}
	try
	{
		int bla;	 
	}
}


The error Xtext gives me is : Duplicate Statement bla.
The same text worked with Xtext 1.0. The expected behaviour would be for
Xtext to recognize the try block as a seperate scope. If the variable had been declared
in a higher level than the blocks I would have understood that, but not like that.

Now I already tried to hack together a "workaround" like this:

public Class<? extends INamesAreUniqueValidationHelper> bindINamesAreUniqueValidationHelper() {
	return NAUVH.class;
}


public class NAUVH extends NamesAreUniqueValidationHelper {

	private String getLastSeg(URI u) {
		return u.segment(u.segmentCount() - 1);
	}

	private boolean isInScope(IEObjectDescription descr, IEObjectDescription decl) {

		int diff = descr.getEObjectURI().fragment().length()
				- decl.getEObjectURI().fragment().length();

		String f1 = descr.getEObjectURI().fragment();
		String f2 = decl.getEObjectURI().fragment();

		int slash1 = f1.lastIndexOf("@");
		int slash2 = f2.lastIndexOf("@");
		String sub1 = f1.substring(0, Math.max(0, slash1));
		String sub2 = f2.substring(0, Math.max(0, slash2));

		return sub1.startsWith(sub2);
	}

	@Override
	public void checkUniqueNames(Iterable<IEObjectDescription> descriptions,
			ValidationMessageAcceptor acceptor) {
		Iterator<IEObjectDescription> iter = descriptions.iterator();
		if (!iter.hasNext())
			return;

		List<IEObjectDescription> decls = new ArrayList<IEObjectDescription>();

		while (iter.hasNext()) {
			IEObjectDescription descr = iter.next();

			for (IEObjectDescription decl : decls) {
				// if in scope and name value is identical, print an error!
				if (isInScope(descr, decl)
						&& descr.getQualifiedName().getLastSegment()
								.equals(decl.getQualifiedName().getLastSegment())) {
					acceptor.acceptError("Duplicate variable "
							+ descr.getQualifiedName().getLastSegment() + " ("
							+ descr.getEObjectURI().fragment() + ")",
							descr.getEObjectOrProxy(), null, -1, null, "");
				}
			}
			decls.add(descr);
		}
	}

	@Override
	public void checkUniqueNames(Iterable<IEObjectDescription> descriptions,
			CancelIndicator cancelIndicator, ValidationMessageAcceptor acceptor) {

		this.checkUniqueNames(descriptions, acceptor);
	}
}

[Updated on: Mon, 07 May 2012 12:49]

Report message to a moderator

Re: Duplicate entries / namespace problems [message #870353 is a reply to message #870248] Mon, 07 May 2012 18:00 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 6302
Registered: July 2009
Senior Member
Hi,

you have following options
(1) the hack
(2) remove the general duplicate validation and add some custom for the scopes it should be checked within
(3) give the stuff names (IQualifiedNameProvider) that takes the context (try, ...) into account

i would prefer (2)

~Christian
Re: Duplicate entries / namespace problems [message #870414 is a reply to message #870353] Tue, 08 May 2012 06:07 Go to previous messageGo to next message
Heinrich Müller is currently offline Heinrich Müller
Messages: 10
Registered: March 2012
Junior Member
Could you please elaborate on option (2) ? That would be really helpful.
Re: Duplicate entries / namespace problems [message #870419 is a reply to message #870414] Tue, 08 May 2012 06:32 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 6302
Registered: July 2009
Senior Member
simply remove the namesuniquevalidation from the workflow and write a java validation as described in the docs.
Re: Duplicate entries / namespace problems [message #974003 is a reply to message #870248] Tue, 06 November 2012 19:51 Go to previous message
Heinrich Müller is currently offline Heinrich Müller
Messages: 10
Registered: March 2012
Junior Member
late reply: a simple fix i found for this, perhaps it will be useful for someone :
public class MyNameProvider extends DefaultDeclarativeQualifiedNameProvider {

	protected QualifiedName qualifiedName(Statement ele)
	{
		if (ele.eContainer() instanceof TryStatement)
		{
			if (EcoreUtil2.isAssignableFrom(MyDslPackage.Literals.STRING_NUMBER_BOOL_DECLARATION, ele.eClass()))
			{
				StringNumberBoolDeclaration decl = (StringNumberBoolDeclaration) ele;
				return QualifiedName.create("try", String.valueOf(NodeModelUtils.findActualNodeFor(ele.eContainer()).getOffset()), decl.getName());
			}
		}
		return null;
	}
}


the only remaining problem: now only duplicates in try-blocks are recognized, so i've got to find another solution to providing a qualifiedname.

[Updated on: Tue, 06 November 2012 19:54]

Report message to a moderator

Previous Topic:implementing Xtext functionality in Xtend
Next Topic:Resolve proxies
Goto Forum:
  


Current Time: Fri Sep 19 06:01:05 GMT 2014

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

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