Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Import issues regarding qualified names
Import issues regarding qualified names [message #1759209] Sat, 08 April 2017 01:20 Go to next message
Finn Rayment is currently offline Finn RaymentFriend
Messages: 26
Registered: April 2017
Junior Member
Hi Christian, (and anyone else available)

With my previous question asking about cross-referencing between files, it works brilliantly, but I have realised a flaw as a result of it.

Lets say I have two folders, one named "first" and one named "second"; they both have two files with the same name. How am I supposed to differentiate? Well I would add in the folder as part of the qualified name to differentiate:

use first.Test
use second.Test

class ChildOfFirst parent first.Test { }
class ChildOfSecond parent second.Test { }


The import code you gave me works fine if I only really use something out of one of these, but when I have two, how can I programmatically differentiate between the two? To be a pain, theres three ways I really need this to go:



  1. If a local type is defined:

    • It can be referenced simply by typing in the types name, example Class


    1. If ANY AMOUNT of external types are defined:

      • Define them by typing in the fully qualified name, example: test.Class


  2. If the local type is NOT defined:

    1. If ONE external type is defined:

      • It can be referenced simply by typing in the types name, example Class



    1. If MORE THAN ONE external type is defined:

      • Define them by typing in the fully qualified name, example: test.Class




Maybe I'm asking for too much Sad I don't know....

My DSL is as follows:

Model

grammar org.thusix.omicron.Omicron with org.eclipse.xtext.common.Terminals

generate omicron "http://www.thusix.org/omicron/Omicron"

Model:
	(
	package=PackageDeclaration
	imports+=ImportDeclaration*
	declarations+=TopDeclaration*
	)?
;

PackageDeclaration:
	'package' name=FQN
;

ImportDeclaration:
	'use' importURI=FQN
;

TopDeclaration:
	Type | VariableDeclaration
;

TypeType:
	Primitive | TypeRef
;

TypeRef:
	ref=[Type | FQN]
;

Type:
	FunctionType | ClassType | StructType | EnumType
;

FunctionType:
	modifiers+=Modifier* 'func' name=ID '(' ')' ':' returnType=TypeType LBRACE
		fields+=Field*
		
	RBRACE
;

ClassType:
	modifiers+=TypeModifier* 'class' name=ID ('parent' superType=TypeRef)? ('inherits' templates+=TypeRef*)? LBRACE
		fields+=Field*
	RBRACE
;

StructType:
	modifiers+=TypeModifier* 'struct' name=ID LBRACE
		declares+=VariableDeclaration*
	RBRACE
;

EnumType:
	modifiers+=TypeModifier* 'enum' name=ID LBRACE
		values+=ID*
	RBRACE
;

Field:
	VariableDeclaration | Type
;

VariableDeclaration:
	modifiers+=Modifier* name=ID ':' type=TypeType
;

/* Statements */

/* Terminals and strings. */

TypeModifier:
	'public' |
	'final' |
	'abstract'
;

Modifier:
	TypeModifier |
	'protected' |
	'private' |
	'static'
;

Primitive:
	name=('int' |
	'long' |
	'short' |
	'float' |
	'double' |
	'str' |
	'char' |
	'bool' |
	'obj' |
	'byte' |
	'nil')
;

FQN:
	ID ('.' ID)*
;

terminal LBRACE: '{' ;
terminal RBRACE: '}' ;


Christian's Import Resolver:

package org.thusix.omicron.resolvers;

import com.google.inject.Inject
import org.eclipse.emf.ecore.EObject
import org.eclipse.xtext.resource.FileExtensionProvider
import org.eclipse.xtext.scoping.impl.ImportUriResolver

public class OmicronImportResolver extends ImportUriResolver {
	
	@Inject
	FileExtensionProvider fileExtensionProvider;
	
	override String apply(EObject from) {
		// TODO make more robust / potentially work in standlone mode if needed
		// or classpath:/my/pack/xxxx.mydsl if needed as well
		var apply = super.apply(from);
		if (apply === null) {
			return apply;
		}
		var result = "platform:/resource/" + from.eResource().getURI().segmentsList().get(1) + "/"
				+ apply.replaceAll("\\.", "/") + "." + fileExtensionProvider.getPrimaryFileExtension();
		return result;
	}

}


I'll include anything else you need if required.
Any help is much appreciated all.

[Updated on: Sat, 08 April 2017 06:37]

Report message to a moderator

Re: Using filenames in cross-references and fixing import issues [message #1759214 is a reply to message #1759209] Sat, 08 April 2017 05:20 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
Hi,

What is your actual question.
How to write a validation that prevents this case?


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Using filenames in cross-references and fixing import issues [message #1759215 is a reply to message #1759214] Sat, 08 April 2017 05:24 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
And regarding the naming.

You can cross reference objects only so you could reference the roots of your Modell
You can adapt the name provider.


Of course this will only work if you import the file
But hey you don't want to import the file

Sorry I am totally confused by your rules of what to use and what to import etc




Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Using filenames in cross-references and fixing import issues [message #1759216 is a reply to message #1759215] Sat, 08 April 2017 05:32 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
And you you can do such things e.g. By I,plementing the scope provider
And create some aliasedebjectdescriptions where when wrapping /transforming
DelegateGetScope(ctx,ref) but implementing this will be pain
And I won't be able to do this for you


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Using filenames in cross-references and fixing import issues [message #1759217 is a reply to message #1759216] Sat, 08 April 2017 05:35 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
The other idea would be to simply give the elements
Simple and qualified names and let the default behaviour do. the job for that

public class StrangeDefaultResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy {
	
	@Override
	public boolean createEObjectDescriptions(EObject eObject, IAcceptor<IEObjectDescription> acceptor) {
		if (eObject instanceof Type) {
			Type type = (Type)eObject;
			if (type.getName() != null) {
				acceptor.accept(EObjectDescription.create(QualifiedName.create(type.getName()), type));
			}
		}
		return super.createEObjectDescriptions(eObject, acceptor);
	}
}


	def Class<? extends IDefaultResourceDescriptionStrategy> bindIDefaultResourceDescriptionStrategy() {
		StrangeDefaultResourceDescriptionStrategy
	}


this has unforunately a first one wins rule.
what you dont like if i got you right


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Sat, 08 April 2017 06:23]

Report message to a moderator

Re: Using filenames in cross-references and fixing import issues [message #1759218 is a reply to message #1759217] Sat, 08 April 2017 06:08 Go to previous messageGo to next message
Finn Rayment is currently offline Finn RaymentFriend
Messages: 26
Registered: April 2017
Junior Member
Hey Christian,
yea it's a bit of a pain, and I wrote this quickly in the morning before work.

I might just adapt the whole model thing to cater for the first part of the question which really just gives users a bit more choice as well...

As for the second part, another way of wording it, is that I want to be able to first of all, be able to reference my imported types with fully qualified names including the package they are located in opposed to just their names, and I would secondly like to be forced to use fully qualified names only if there is more than one of them imported with the same name, or a local one exists.
Re: Using filenames in cross-references and fixing import issues [message #1759219 is a reply to message #1759217] Sat, 08 April 2017 06:22 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
well you can adapt this as well but i dont know if you can live with the perfomance impacts

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.IResourceDescription;
import org.eclipse.xtext.resource.IResourceDescriptions;
import org.eclipse.xtext.resource.ISelectable;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider;
import org.eclipse.xtext.scoping.impl.MultimapBasedSelectable;
import org.eclipse.xtext.scoping.impl.SelectableBasedScope;

import com.google.common.base.Predicate;
import com.google.common.collect.Lists;

public class StrangeImportUriGlobalScopeProvider extends ImportUriGlobalScopeProvider {
	
	@Override
	protected IScope getScope(Resource resource, boolean ignoreCase, EClass type, Predicate<IEObjectDescription> filter) {
		final LinkedHashSet<URI> uniqueImportURIs = getImportedUris(resource);
		IResourceDescriptions descriptions = getResourceDescriptions(resource, uniqueImportURIs);
		List<URI> urisAsList = Lists.newArrayList(uniqueImportURIs);
		Collections.reverse(urisAsList);
		IScope scope = IScope.NULLSCOPE;
		
		List<IEObjectDescription> descs = new ArrayList<>();
		for (URI uri : urisAsList) {
			IResourceDescription description = descriptions.getResourceDescription(uri);
			descs.addAll(Lists.newArrayList(description.getExportedObjects()));
		}
		MultimapBasedSelectable selectable = new MultimapBasedSelectable(descs);
		return new SelectableBasedScope2(scope, selectable, filter, type, ignoreCase);
//		for (URI uri : urisAsList) {
//			scope = createLazyResourceScope(scope, uri, descriptions, type, filter, ignoreCase);
//		}
//		return scope;
	}
	
	protected IScope createLazyResourceScope(IScope parent, final URI uri, final IResourceDescriptions descriptions,
			EClass type, final Predicate<IEObjectDescription> filter, boolean ignoreCase) {
		IResourceDescription description = descriptions.getResourceDescription(uri);
		return SelectableBasedScope.createScope(parent, description, filter, type, ignoreCase);
	}
	
	static class SelectableBasedScope2 extends SelectableBasedScope {

		public SelectableBasedScope2(IScope outer, ISelectable selectable, Predicate<IEObjectDescription> filter,
				EClass type, boolean ignoreCase) {
			super(outer, selectable, filter, type, ignoreCase);
		}
		
		@Override
		protected IEObjectDescription getSingleLocalElementByName(QualifiedName name) {
			Iterable<IEObjectDescription> result = getLocalElementsByName(name);
			Iterator<IEObjectDescription> iterator = result.iterator();
			if (iterator.hasNext()) {
				IEObjectDescription next = iterator.next();
				if (iterator.hasNext()) {
					return null;
				}
				return next;
			}
			return null;
		}
		
	}

}




	override bindIGlobalScopeProvider() {
		StrangeImportUriGlobalScopeProvider
	}


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Using filenames in cross-references and fixing import issues [message #1759220 is a reply to message #1759219] Sat, 08 April 2017 06:24 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
can you have a look at my other two posts with code if they help you?

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Using filenames in cross-references and fixing import issues [message #1759221 is a reply to message #1759220] Sat, 08 April 2017 06:26 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
p.s. local names win over global ones in both cases

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Using filenames in cross-references and fixing import issues [message #1759222 is a reply to message #1759220] Sat, 08 April 2017 06:28 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
p.s: and i still dont understand the first part of your question. i really dont.

you "use" files, not classes.


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Using filenames in cross-references and fixing import issues [message #1759223 is a reply to message #1759222] Sat, 08 April 2017 06:35 Go to previous messageGo to next message
Finn Rayment is currently offline Finn RaymentFriend
Messages: 26
Registered: April 2017
Junior Member
Thanks for the code, I'll set it all out now and see how it goes.
As for the first part of the question, just ignore it and pretend it never happened. I'll edit it out. Very Happy
Re: Using filenames in cross-references and fixing import issues [message #1759225 is a reply to message #1759223] Sat, 08 April 2017 07:05 Go to previous messageGo to next message
Finn Rayment is currently offline Finn RaymentFriend
Messages: 26
Registered: April 2017
Junior Member
Alrighty that seems to have not done a thing sorry...

My runtime module is as follows:

/*
 * generated by Xtext 2.11.0
 */
package org.thusix.omicron

import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy
import org.eclipse.xtext.scoping.impl.ImportUriResolver
import org.thusix.omicron.resolvers.OmicronImportResolver
import org.thusix.omicron.resolvers.OmicronNameProvider
import org.thusix.omicron.resolvers.StrangeDefaultResourceDescriptionStrategy
import org.thusix.omicron.resolvers.StrangeImportUriGlobalScopeProvider

/**
 * Use this class to register components to be used at runtime / without the Equinox extension registry.
 */
class OmicronRuntimeModule extends AbstractOmicronRuntimeModule {

	override bindIQualifiedNameProvider() {
		OmicronNameProvider
	}
	
	def Class<? extends ImportUriResolver> bindImportUriResolver() {
		OmicronImportResolver
	}
	
	override bindIGlobalScopeProvider() {
		StrangeImportUriGlobalScopeProvider
	}
	
	def Class<? extends IDefaultResourceDescriptionStrategy> bindIDefaultResourceDescriptionStrategy() {
		StrangeDefaultResourceDescriptionStrategy
	}

}


And it just won't find them at all.
I removed the first part of the question, but I can't even get it to work on my own so I really need your help!

You said earlier that you are confused by my mechanism of imports. In Java, you import classes. In the DSL, you can import files, and classes in those files. At the moment from what we currently have, I am only able to import a class inside of a file.

This is why I was asking how to get a filename to work as a cross-reference. My generator can cope just fine as long as it gets recognised as one in the code....

index.php/fa/29002/0/

[Updated on: Sat, 08 April 2017 07:06]

Report message to a moderator

Re: Using filenames in cross-references and fixing import issues [message #1759226 is a reply to message #1759225] Sat, 08 April 2017 07:22 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
you can reference the model


xxx=[Model|FQN]

but this wont work since you need a use "xxxx.yyyy.Model" as well.
this is what makes me understand zero of your requirements Sad

and i dont understand your screenshot.

it should be

use src.Deck. why do you have test.Deck?








Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Using filenames in cross-references and fixing import issues [message #1759227 is a reply to message #1759226] Sat, 08 April 2017 07:36 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
p.s.:

if you dont care about files at all but about logical elements only

this would have to be done 100% differently.

but as i said: i dont understand how your

- physical package
- physical file name
- modeled package
- modeled file
- modeled class

play together and how names are built


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Using filenames in cross-references and fixing import issues [message #1759228 is a reply to message #1759226] Sat, 08 April 2017 07:37 Go to previous messageGo to next message
Finn Rayment is currently offline Finn RaymentFriend
Messages: 26
Registered: April 2017
Junior Member
Pardon me, I use "test.Deck" because as I generate my Java source, that package declaration is what specifies the folder I place my files in.

The src-gen folder has a "test" package with both files in it.

Back in my previous questions, you were able to help me setup an import system that would trace through that package declaration system, not the literal file system, so regardless of where the files are located, I still want the package-system to be used.

Once I get the DSL going I'll obviously stick an error-checker in to force people to make the file system adhere to the package system. So for now, regardless of what the file system says, please assume that it is identical to that of the package one.

I've taken another screenshot with a bunch of examples of the current state, and some comments as to what is happening.

index.php/fa/29003/0/

PS: I'm slapping that [Type | Model] thing in now to see how it goes.
PPS: It works brilliant! Thankyou. First part of the problem solved. Now just this above import nonsense.

[Updated on: Sat, 08 April 2017 07:41]

Report message to a moderator

Re: Using filenames in cross-references and fixing import issues [message #1759229 is a reply to message #1759228] Sat, 08 April 2017 07:39 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
can you share your example project

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Using filenames in cross-references and fixing import issues [message #1759230 is a reply to message #1759229] Sat, 08 April 2017 07:42 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
and still the question

: if in model

package a.b.c
file Whatever
class D {}

the classes name is a.b.c.D? or a.b.c.Whatever.D

or you have to import it like

use a.b.c.Whatever
and reference it like a.b.c.D ???

then why not use it like in java?



Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Using filenames in cross-references and fixing import issues [message #1759231 is a reply to message #1759229] Sat, 08 April 2017 07:45 Go to previous messageGo to next message
Finn Rayment is currently offline Finn RaymentFriend
Messages: 26
Registered: April 2017
Junior Member
Are you talking about the project in the screenshots?

I've got it on Dropbox here.
Re: Using filenames in cross-references and fixing import issues [message #1759232 is a reply to message #1759230] Sat, 08 April 2017 07:50 Go to previous messageGo to next message
Finn Rayment is currently offline Finn RaymentFriend
Messages: 26
Registered: April 2017
Junior Member
Nice example.

The class should be referenced like a.b.c.Whatever.D, in all scenarios.
When you import things, your not importing that D class, your going through Whatever, which is a file/class, and then to D.

If you want to import OR reference D and ignore Whatever, then do with the following:

use a.b.c.Whatever.D // bypasses Whatever and goes straight to D

class Other parent D {} // since theres no local references
class Other parent a.b.c.Whatever.D // full name

Re: Using filenames in cross-references and fixing import issues [message #1759234 is a reply to message #1759232] Sat, 08 April 2017 08:08 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
maybe

public class StrangeNameProvider extends DefaultDeclarativeQualifiedNameProvider {
	
	QualifiedName qualifiedName(Model type) {
                // use complete file name
		String[] segments = type.eResource().getURI().trimFileExtension().segments();
		return QualifiedName.create(Arrays.copyOfRange(segments, 2, segments.length));
	}

}


// make model be a type
Model returns Type: {Model}
	(
	package=PackageDeclaration
	imports+=ImportDeclaration*
	declarations+=TopDeclaration*
	)?
;


take care of type types and model type available under simply/qualified name
public class StrangeDefaultResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy {
	
	@Override
	public boolean createEObjectDescriptions(EObject eObject, IAcceptor<IEObjectDescription> acceptor) {
		if (eObject instanceof ClassType) {
			ClassType type = (ClassType)eObject;
			if (type.getName() != null) {
				acceptor.accept(EObjectDescription.create(QualifiedName.create(type.getName()), type));
			}
		} else if (eObject instanceof EnumType) {
			EnumType type = (EnumType)eObject;
			if (type.getName() != null) {
				acceptor.accept(EObjectDescription.create(QualifiedName.create(type.getName()), type));
			}
		} else if (eObject instanceof StructType) {
			StructType type = (StructType)eObject;
			if (type.getName() != null) {
				acceptor.accept(EObjectDescription.create(QualifiedName.create(type.getName()), type));
			}
		} else if (eObject instanceof FunctionType) {
			FunctionType type = (FunctionType)eObject;
			if (type.getName() != null) {
				acceptor.accept(EObjectDescription.create(QualifiedName.create(type.getName()), type));
			}
		}  else if (eObject instanceof Model) {
			Model type = (Model)eObject;
			acceptor.accept(EObjectDescription.create(QualifiedName.create(type.eResource().getURI().trimFileExtension().lastSegment()), type));
		}
		return super.createEObjectDescriptions(eObject, acceptor);
	}
}


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Using filenames in cross-references and fixing import issues [message #1759236 is a reply to message #1759234] Sat, 08 April 2017 08:32 Go to previous messageGo to next message
Finn Rayment is currently offline Finn RaymentFriend
Messages: 26
Registered: April 2017
Junior Member
Christian you are so close!
I just want you to know that I feel terrible for relying on you for something this stupidly specific, and definitely appreciate all the help that you have given me, and I couldn't of done half of this without you!

It looks like a mess, but the real only issue is that the importer is now looking through every scope of the imported file.

Same Dropbox link too.

index.php/fa/29004/0/
Re: Using filenames in cross-references and fixing import issues [message #1759237 is a reply to message #1759236] Sat, 08 April 2017 08:38 Go to previous messageGo to next message
Finn Rayment is currently offline Finn RaymentFriend
Messages: 26
Registered: April 2017
Junior Member
You know what, I think the easier way to put this is do exactly what Java does, except take the Model as a valid type, and only have the need to scope through packages without going back say two folders to stdlib, or even a classpath-source folder.

[Updated on: Sat, 08 April 2017 08:43]

Report message to a moderator

Re: Using filenames in cross-references and fixing import issues [message #1759242 is a reply to message #1759237] Sat, 08 April 2017 09:06 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
well the number of customizations is going to explode.
i have my doubt there is anybody on the planet that can understand the requirements ....

and they get stranger again,

why cant you import nested classes under the simple name if it is unique ?!? ?????????

i have the feeling i should stop supporting you at this point Sad
that is too much WORK for me.

	override configureIScopeProviderDelegate(Binder binder) {
		binder.bind(IScopeProvider).annotatedWith(Names.named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(StrangeImportedNamespaceAwareLocalScopeProvider);
	
	}


public class StrangeImportedNamespaceAwareLocalScopeProvider extends ImportedNamespaceAwareLocalScopeProvider {
	
	@Inject
	SimpleNameProvider2 snp;
	
	@Override
	protected ISelectable internalGetAllDescriptions(Resource resource) {
		Iterable<EObject> allContents = new Iterable<EObject>(){
			@Override
			public Iterator<EObject> iterator() {
				return EcoreUtil.getAllContents(resource, false);
			}
		}; 
		Iterable<IEObjectDescription> allDescriptions = Scopes.scopedElementsFor(allContents, snp);
		return new MultimapBasedSelectable(allDescriptions);
	}
	
	@Override
	protected List<ImportNormalizer> getImportedNamespaceResolvers(EObject context, boolean ignoreCase) {
		List<ImportNormalizer> importedNamespaceResolvers = super.getImportedNamespaceResolvers(context, ignoreCase);
		if (context instanceof Model) {
			for (ImportDeclaration decl : ((Model) context).getImports()) {
				// relative import, might no do what you want
				// class AClass parent TestClass.NestedClass {} 
				importedNamespaceResolvers.add(doCreateImportNormalizer(getQualifiedNameConverter().toQualifiedName(decl.getImportURI()), true, ignoreCase));
			}
		}
		return importedNamespaceResolvers;
	}
	
	static class SimpleNameProvider2 extends SimpleNameProvider {
		@Override
		public QualifiedName getFullyQualifiedName(EObject obj) {
			if (obj instanceof Model) {
				return QualifiedName.create(obj.eResource().getURI().trimFileExtension().lastSegment());
			}
			return super.getFullyQualifiedName(obj);
		}
	}

}


maybe you should do a completely different approach and

- remove the customization of bindIGlobalScopeProvider
- remove the customization of bindImportUriResolver
- remove the customization of IDefaultResourceDescriptionStrategy
- remove the customization of configureIScopeProviderDelegate

- change the grammar to

ImportDeclaration:
	'use' mode=[Model|FQN]
;


and implement this one here:

class MyDslFinnScopeProvider extends AbstractMyDslFinnScopeProvider {
	
	override getScope(EObject context, EReference reference) {
		if (MyDslFinnPackage.Literals.TYPE_REF__REF === reference) {
			val List<IEObjectDescription> scope = new ArrayList
			// TODO traverse content up to model (EcoreUtil2.getContainerOfType)
			// collect all local types and the types referenced in the import.
			// calculate the visible elements and there name
			val EObject someObject = ....
			val QualifiedName name = QualifiedName.create("a","b","C","D")
			scope.add(EObjectDescription.create(name, someObject));
			return new SimpleScope(IScope.NULLSCOPE, scope)
		}
		
		
		super.getScope(context, reference)
	}

}



Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Using filenames in cross-references and fixing import issues [message #1759244 is a reply to message #1759242] Sat, 08 April 2017 12:08 Go to previous messageGo to next message
Finn Rayment is currently offline Finn RaymentFriend
Messages: 26
Registered: April 2017
Junior Member
Thanks for all your help Christian, I'm glad you've been able to support me for so long with such absurd requests. If you feel it is too much for you, please let me know! You come before me! Sad

I've been poking around for a while, and have come to an almost perfectly clear solution. If you look at the below picture:

index.php/fa/29008/0/

The middle section specifically, I can get the three of them to work, but the other three wont work. Thats fine, because I want you to take a look at the DSLNameProvider:
class OmicronNameProvider extends DefaultDeclarativeQualifiedNameProvider {
	
	def QualifiedName qualifiedName(Model type) {
		return QualifiedName.create(type.eResource().getURI().trimFileExtension().lastSegment());
	}
	
	/*def QualifiedName qualifiedName(Model type) {
        // use complete file name
		var String[] segments = type.eResource().getURI().trimFileExtension().segments();
		return QualifiedName.create(Arrays.copyOfRange(segments, 2, segments.length));
	}
	*/
}


This picture, is taken using the top solution. Except! If I instead decide to use the bottom function, and comment out the top one, this happens:

index.php/fa/29006/0/

See how the errors flip between the two? I think I understand why this happens too, because it's validating one way as being correct but not the other. I was wondering if you know how to make it accept both of these functions, or somehow merge the two together? If we can get it to accept both, then thats literally all there is to it!

I also tinkered with the RuntimeModule, and here are the functions you gave me that seemed to work correctly. I'm sorry about before with all the crap with it... Confused
class OmicronRuntimeModule extends AbstractOmicronRuntimeModule {

	// Lets me use the local file as a type both with and without the folder as a part of the name...
	override configureIScopeProviderDelegate(Binder binder) {
		binder.bind(IScopeProvider).annotatedWith(Names.named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(StrangeImportedNamespaceAwareLocalScopeProvider);
	}

	// Requires imports to be added before they become available in the local scope.
	override bindIGlobalScopeProvider() {
		ImportUriGlobalScopeProvider
	}

	// Provides the name of the type. This includes the folder prefixes.
	override bindIQualifiedNameProvider() {
		OmicronNameProvider
	}
	
	// Converts the import into a valid format.
	def Class<? extends ImportUriResolver> bindImportUriResolver() {
		OmicronImportUriResolver
	}

}


And a few modifications to StrangeImportedNamespaceAwareLocalScopeProvider which was very useful so thankyou!
package org.thusix.omicron.resolvers;

import java.util.Arrays;
import java.util.Iterator;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.naming.SimpleNameProvider;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.ISelectable;
import org.eclipse.xtext.scoping.Scopes;
import org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider;
import org.eclipse.xtext.scoping.impl.MultimapBasedSelectable;
import org.thusix.omicron.omicron.ImportDeclaration;
import org.thusix.omicron.omicron.Model;
import org.thusix.omicron.omicron.Type;

import com.google.inject.Inject;

public class StrangeImportedNamespaceAwareLocalScopeProvider extends ImportedNamespaceAwareLocalScopeProvider {
	
	@Inject
	SimpleNameProvider2 snp;
	
	@Override
	protected ISelectable internalGetAllDescriptions(Resource resource) {
		Iterable<EObject> allContents = new Iterable<EObject>(){
			@Override
			public Iterator<EObject> iterator() {
				return EcoreUtil.getAllContents(resource, false);
			}
		}; 
		Iterable<IEObjectDescription> allDescriptions = Scopes.scopedElementsFor(allContents, snp);
		return new MultimapBasedSelectable(allDescriptions);
	}
	
	static class SimpleNameProvider2 extends SimpleNameProvider {
		// Used for local qualified name usage with folder prefix at the beginning.
		EObject localWithFolders = null;
		@Override
		public QualifiedName getFullyQualifiedName(EObject obj) {
			if (obj instanceof ImportDeclaration) {
				localWithFolders = obj;
			}
			if (obj instanceof Type && localWithFolders != null) {
				String[] segments = localWithFolders.eResource().getURI().trimFileExtension().segments();
				localWithFolders = null;
				return QualifiedName.create(Arrays.copyOfRange(segments, 2, segments.length));
			}
 			if (obj instanceof Model) {
				return QualifiedName.create(obj.eResource().getURI().trimFileExtension().lastSegment());
			}
			return super.getFullyQualifiedName(obj);
		}
	}

}

[Updated on: Sat, 08 April 2017 12:12]

Report message to a moderator

Re: Using filenames in cross-references and fixing import issues [message #1759245 is a reply to message #1759244] Sat, 08 April 2017 12:43 Go to previous message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
Hi,

i customized StrangeImportUriGlobalScopeProvider and StrangeDefaultResourceDescriptionStrategy for a reason

the last one --> StrangeDefaultResourceDescriptionStrategy is the one that takes care that stuff is available on both names

StrangeImportedNamespaceAwareLocalScopeProvider does relative imports (based on the global names)


but i strogly recommend you to go the other approach (implement mydslscopeprovider)
that will give you complete freedom


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Sat, 08 April 2017 12:46]

Report message to a moderator

Previous Topic:2 DSLs and 1 Ecore-Model
Next Topic:Cross Reference
Goto Forum:
  


Current Time: Fri Apr 19 05:58:42 GMT 2024

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

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

Back to the top