|
Re: ImportedNamespaceAwareLocalScopeProvider should check the path [message #845808 is a reply to message #845657] |
Sun, 15 April 2012 12:42 |
Sebastian Zarnekow 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 |
Phil R Messages: 99 Registered: September 2011 |
Member |
|
|
Hi Sebastian,
Sebastian Zarnekow wrote on Sun, 15 April 2012 14:42SomeOther.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:42Nevertheless, 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
|
|
|
Powered by
FUDForum. Page generated in 0.03680 seconds