Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » ImportedNamespaceAwareLocalScopeProvider should check the path
ImportedNamespaceAwareLocalScopeProvider should check the path [message #845657] Sun, 15 April 2012 09:18 Go to next message
Phil R is currently offline Phil RFriend
Messages: 99
Registered: September 2011
Member
Hi,

The DSL has both namespaces and importUri, so the best way is to use only the ImportedNamespaceAwareLocalScopeProvider and let it be responsible for including files also. This works great. However the files that are imported should be localized by their path. Now it works if the file is in the workspace and then xtext automatically finds it which shouldn't if the file is in a different folder.
I tried in ImportedNamespaceAwareLocalScopeProvider:
protected List<ImportNormalizer> internalGetImportedNamespaceResolvers(final EObject context, boolean ignoreCase) {
		List<ImportNormalizer> importedNamespaceResolvers = Lists.newArrayList();
		SimpleAttributeResolver<EObject, String> importResolver = 
				SimpleAttributeResolver.newResolver(String.class, "importedNamespace");
		EList<EObject> eContents = context.eContents();
			
		for (EObject child : eContents) {
			
			String value = importResolver.getValue(child);			
			if (value != null) {	
				if (child instanceof IncludeFile) {
					// check path to child..
					IWorkspace workspace = ResourcesPlugin.getWorkspace();
					IPathVariableManager pathMan = workspace.getPathVariableManager();

					IPath pathToChild = new Path(value);
					System.out.println(pathToChild.toOSString());
					if (pathMan.validateValue(pathToChild).isOK())
						System.out.println("path found:"+value);
					value = pathToChild.lastSegment();
					System.out.println("adding:" + value);
				}
				
				ImportNormalizer resolver = createImportedNamespaceResolver(value+"::*", ignoreCase);
				if (resolver != null)
					importedNamespaceResolvers.add(resolver);
			}
		}
		if (context instanceof Namespace) {
			
			ImportNormalizer resolver2 = createImportedNamespaceResolver(((Namespace)context).getName()+"::*", ignoreCase);
			if (resolver2 != null) {
				importedNamespaceResolvers.add(resolver2);
			}
		}				
		return importedNamespaceResolvers;
	}

But the "path checking function": pathMan.validateValue(pathToChild).isOK() does not work and also removing the path and just adding the filename to the resolver does not work. If a file is located in a folder and no path is given to the folder (just the filename) than it works...

So my questions are:
Should I avoid the resourcesplugin of eclipse but use tools provided by xtext?
Why doesn't the resolver works if I just add the filename and removing the path to it ?

Regards,
Phil
Re: ImportedNamespaceAwareLocalScopeProvider should check the path [message #845808 is a reply to message #845657] Sun, 15 April 2012 12:42 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 3118
Registered: July 2009
Senior Member
Hi Phil,

I'm afraid I cannot fully follow your question. Please provide a small
example to illustrate the problem.

What I got was:

=== Content of YourDsl.file ===

include 'SomeOther.file'

=== / ===

SomeOther.file is located next the YourDsl.file in the file system. You
want to achieve that SomeOther.file cannot be found because it should be
read from somewhere else? That does not sound to convincing to me thus I
think I got it wrong.

Nevertheless, I guess you should learn about EMFs URI mechanism which
usually works relative to the current resource location. That's why
SomeOther.file will be loaded if it is in the same directory. Relative
navigation or absolute URIs are possible too:

include '../../otherDir/SomeOther.file'

or

include 'platform:/resource/yourProject/src/some/path/to/a.file'

Regards,
Sebastian
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com

Am 15.04.12 11:18, schrieb Phil R:
> Hi,
>
> The DSL has both namespaces and importUri, so the best way is to use
> only the ImportedNamespaceAwareLocalScopeProvider and let it be
> responsible for including files also. This works great. However the
> files that are imported should be localized by their path. Now it works
> if the file is in the workspace and then xtext automatically finds it
> which shouldn't if the file is in a different folder.
> I tried in ImportedNamespaceAwareLocalScopeProvider:
> protected List<ImportNormalizer>
> internalGetImportedNamespaceResolvers(final EObject context, boolean
> ignoreCase) {
> List<ImportNormalizer> importedNamespaceResolvers = Lists.newArrayList();
> SimpleAttributeResolver<EObject, String> importResolver =
> SimpleAttributeResolver.newResolver(String.class, "importedNamespace");
> EList<EObject> eContents = context.eContents();
>
> for (EObject child : eContents) {
>
> String value = importResolver.getValue(child);
> if (value != null) {
> if (child instanceof IncludeFile) {
> // check path to child..
> IWorkspace workspace = ResourcesPlugin.getWorkspace();
> IPathVariableManager pathMan = workspace.getPathVariableManager();
>
> IPath pathToChild = new Path(value);
> System.out.println(pathToChild.toOSString());
> if (pathMan.validateValue(pathToChild).isOK())
> System.out.println("path found:"+value);
> value = pathToChild.lastSegment();
> System.out.println("adding:" + value);
> }
>
> ImportNormalizer resolver = createImportedNamespaceResolver(value+"::*",
> ignoreCase);
> if (resolver != null)
> importedNamespaceResolvers.add(resolver);
> }
> }
> if (context instanceof Namespace) {
>
> ImportNormalizer resolver2 =
> createImportedNamespaceResolver(((Namespace)context).getName()+"::*",
> ignoreCase);
> if (resolver2 != null) {
> importedNamespaceResolvers.add(resolver2);
> }
> }
> return importedNamespaceResolvers;
> }
> But the "path checking function":
> pathMan.validateValue(pathToChild).isOK() does not work and also
> removing the path and just adding the filename to the resolver does not
> work. If a file is located in a folder and no path is given to the
> folder (just the filename) than it works...
>
> So my questions are:
> Should I avoid the resourcesplugin of eclipse but use tools provided by
> xtext?
> Why doesn't the resolver works if I just add the filename and removing
> the path to it ?
>
> Regards,
> Phil
Re: ImportedNamespaceAwareLocalScopeProvider should check the path [message #845996 is a reply to message #845808] Sun, 15 April 2012 16:49 Go to previous message
Phil R is currently offline Phil RFriend
Messages: 99
Registered: September 2011
Member
Hi Sebastian,
Sebastian Zarnekow wrote on Sun, 15 April 2012 14:42
SomeOther.file is located next the YourDsl.file in the file system. You
want to achieve that SomeOther.file cannot be found because it should be
read from somewhere else? That does not sound to convincing to me thus I
think I got it wrong.

No, It does not need to be read from somewhere else. It should be read as you pointed below:
Sebastian Zarnekow wrote on Sun, 15 April 2012 14:42
Nevertheless, I guess you should learn about EMFs URI mechanism which
usually works relative to the current resource location. That's why
SomeOther.file will be loaded if it is in the same directory. Relative
navigation or absolute URIs are possible too:

include '../../otherDir/SomeOther.file'

That's what I want to achieve however it only works as include 'SomeOther.file' independently of the path..
I can't use importURI because I need most of the namespace aware scoping functionality (I also use namespace keywords in the dsl as shown in the example below)

I'll give an example:

the structure of the project is like:
main.dsl
folder\child.dsl

Then in the main.dsl:
#include 'child.dsl' // works but shouldn't 
#include 'folder/child.dsl' // does not work <- this is what I want

namespace mainNS {
  using namespace childNS // e.g. namespace defined in child.dsl
} 


However I got above working with a scopefilter on the #include tag and
for the fqn the last segment of the path is used (child.dsl because that works).
My filter looks like:
	private class IncludedFilesFilter implements Predicate<IEObjectDescription> {
		
		private EObject context;
		private IncludedFilesFilter(EObject context) {
			this.context = context;
		}

		private SimpleAttributeResolver<EObject, String> resolver;
		
		@Override
		public boolean apply(IEObjectDescription input) {				
			// keep the owning resource
			if (context.eResource().getURI().lastSegment() != null) {
				if (context.eResource().getURI().lastSegment().equals(input.getQualifiedName().getFirstSegment())) {
					return true;
				}
			}
			resolver = SimpleAttributeResolver.newResolver(String.class, "importedNamespace");
			// standard library is always included:
			if (input.getQualifiedName().getFirstSegment().equals(STANDARDLIB)) return true;
			
			// keep the included resources
			EObject model = context;
			// find model tag where include statements are located:
			while (!(model instanceof Model)) model = model.eContainer();
			if (model instanceof Model) {
				for (IncludeFile file : ((Model)model).getIncludes()) {									
					// check if uri exists:
					String strUri = resolver.apply(file);
					if (strUri != null) {
						URI uri = URI.createURI(strUri);					
						if (EcoreUtil2.isValidUri(context.eResource(), uri)) {												
							if(	input.getQualifiedName().getFirstSegment().equals(uri.lastSegment())) {						
								return true;
							}
						}
					}
																
				}
			}			
			return false;
		}
	}


The ImportedNamespaceAwareLocalScopeProvider will only add the last segment of the include files in the resolvers. This way it all works great.
Do you see any bugs that could happen?

Regards,
Phil
Previous Topic:Need some help
Next Topic:QuickFix error
Goto Forum:
  


Current Time: Fri Apr 19 22:02:27 GMT 2024

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

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

Back to the top