Skip to main content



      Home
Home » Modeling » TMF (Xtext) » (XText 1.0) importUri and ProposalProvider("unresolvable" Proxies provided for imported elements)
(XText 1.0) importUri and ProposalProvider [message #787997] Wed, 01 February 2012 03:12 Go to next message
Eclipse UserFriend
Hi,

I create a dsl using Xtext 1.0. I use the "importUri" method and all work fine.

I implement some methods for my model elements in the label provider but due to the
getDisplayString() method in org.eclipse.xtext.ui.editor.contentassist.AbstractContentProposalProvider they are never called for content assist proposal, only elements name are displayed.
I tried solve this by overriding the getDisplayString method in my ProposalProvider.
	@Override
	protected String getDisplayString(EObject modelElement, String qualifiedName, String shortName) {
		//try resolve proxy but don't work
		if (modelElement.eIsProxy()) {
			modelElement = EcoreUtil.resolve(modelElement, modelElement.eResource());
		}
		String displayString = getLabelProvider().getText(modelElement);
		return displayString;
	}

when the ProposalProvider selects an element from imported model the selected modelElement is a proxy with a null eResource() and i can't create a correct displayString.

Maybe my workflow configuration is incomplete for Import and contentAssist support:

module com.sysord.Gvbscript

import org.eclipse.emf.mwe.utils.*
import org.eclipse.xtext.generator.*
import org.eclipse.xtext.ui.generator.*

var grammarURI = "classpath:/com/sysord/Gvbscript.xtext"
var file.extensions = "gvbs"
var projectName = "com.sysord.gvbscript"
var runtimeProject = "../${projectName}"

Workflow {
    bean = StandaloneSetup {
		platformUri = "${runtimeProject}/.."
	}

	component = DirectoryCleaner {
		directory = "${runtimeProject}/src-gen"
	}

	component = DirectoryCleaner {
		directory = "${runtimeProject}.ui/src-gen"
	}

	component = Generator {
		pathRtProject = runtimeProject
		pathUiProject = "${runtimeProject}.ui"
		projectNameRt = projectName
		projectNameUi = "${projectName}.ui"
		language = {
			uri = grammarURI
			fileExtensions = file.extensions

			// Java API to access grammar elements (required by several other fragments)
			fragment = grammarAccess.GrammarAccessFragment {}

			// generates Java API for the generated EPackages 
			fragment = ecore.EcoreGeneratorFragment {
			// referencedGenModels = "uri to genmodel, uri to next genmodel"
			}

			// the serialization component
			fragment = parseTreeConstructor.ParseTreeConstructorFragment {}

			// a custom ResourceFactory for use with EMF 
			fragment = resourceFactory.ResourceFactoryFragment {
				fileExtensions = file.extensions
			}

			// The antlr parser generator fragment.
//			fragment = parser.antlr.XtextAntlrGeneratorFragment {
//			  	options = {
//			//		backtrack = true
//				}
//			}
			fragment = parser.antlr.ex.rt.AntlrGeneratorFragment {
				options = {
					ignoreCase = true
				}
			}

			// java-based API for validation 
			fragment = validation.JavaValidatorFragment {
				composedCheck = "org.eclipse.xtext.validation.ImportUriValidator"
				composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
				// registerForImportedPackages = true
			}

			// scoping and exporting API
			 fragment = scoping.ImportURIScopingFragment {
			 	ignoreCase = true
			 }
			 
			 fragment = exporting.SimpleNamesFragment {}

			// scoping and exporting API 
//			fragment = scoping.ImportNamespacesScopingFragment {}
//			fragment = exporting.QualifiedNamesFragment {}
//			fragment = builder.BuilderIntegrationFragment {}

			// formatter API 
			fragment = formatting.FormatterFragment {}

			// labeling API 
			fragment = labeling.LabelProviderFragment {}

			// outline API 
			fragment = outline.TransformerFragment {}
			fragment = outline.OutlineNodeAdapterFactoryFragment {}
			fragment = outline.QuickOutlineFragment {}

			// quickfix API 
			fragment = quickfix.QuickfixProviderFragment {}

			// content assist API  
			fragment = contentAssist.JavaBasedContentAssistFragment {}

			// generates a more lightweight Antlr parser and lexer tailored for content assist  
//			fragment = parser.antlr.XtextAntlrUiGeneratorFragment {
//			}
			fragment = org.eclipse.xtext.generator.parser.antlr.ex.ca.ContentAssistParserGeneratorFragment{
					options = {
					ignoreCase = true
				}				
			}

			// project wizard (optional) 
			// fragment = projectWizard.SimpleProjectWizardFragment {
			// 		generatorProjectName = "${projectName}.generator" 
			//		modelFileExtension = file.extensions
			// }
		}
	}


I create a workaround using scopeProvider and resolving EObjectDescription in the ProposalProvider, but i think it exists an easier way. Does someone know the solution ?

Thanks,
P. Palau
Re: (XText 1.0) importUri and ProposalProvider [message #789291 is a reply to message #787997] Thu, 02 February 2012 15:24 Go to previous messageGo to next message
Eclipse UserFriend
Hi,

you have basically these options

(1) resolve the proxy (which might be slow and you have to overwrite all the stuff up to org.eclipse.xtext.ui.editor.contentassist.AbstractJavaBasedContentProposalProvider.DefaultProposalCreator.apply(IEObjectDescription)
where you have access to the context which gives you an model object you can resolve against)
(2) enrich the IEObjectDescriptions with the Information you need (which might be painful since you have to provide a custom IResourceDescription.Manager)

~Christian
Re: (XText 1.0) importUri and ProposalProvider [message #808241 is a reply to message #787997] Mon, 27 February 2012 10:14 Go to previous message
Eclipse UserFriend
Hi Christian,

Thanks for your help.
I'm sorry, i did not receive (or saw) notification about your post and just found it yesterday.
I used resolve proxy, it's slow but it works. I created generic behaviour in the ProposalProvider to resolve crossref using ScopeProvider (maybe it's not a good thing). I put the code, it could help some users.

public class GvbscriptProposalProvider extends AbstractGvbscriptProposalProvider {

	@Inject
	IScopeProvider scopeProvider;

	@Override
	public void completeAssignment(Assignment assignment, ContentAssistContext contentAssistContext, ICompletionProposalAcceptor acceptor) {
		
		//when assignment is a crossreference 
		if(CrossReference.class.isAssignableFrom(assignment.getTerminal().getClass())){
			CrossReference crossReference = (CrossReference)assignment.getTerminal();
			ParserRule containingParserRule = GrammarUtil.containingParserRule(crossReference);
			if (!GrammarUtil.isDatatypeRule(containingParserRule)) {				
				//Look for complete method override
				boolean existsMethodOverride;
				try {
					String methodName = "complete" + Strings.toFirstUpper(containingParserRule.getName()) + "_" + Strings.toFirstUpper(assignment.getFeature());
					Method completeMethod = this.getClass().getMethod(methodName, EObject.class, Assignment.class, ContentAssistContext.class, ICompletionProposalAcceptor.class);
					existsMethodOverride = (completeMethod.getDeclaringClass().equals(this.getClass()));
				} catch (Exception e) {
					existsMethodOverride = false;
				}
				
				//No complete method override, Use generic complete method for crossReference
				if(!existsMethodOverride){
					completeUsingScopeProvider(crossReference, contentAssistContext, acceptor);					
				}
			}
			
		}

		//Use standard base method.
		super.completeAssignment(assignment, contentAssistContext, acceptor);
		
	}

//
// Custom complete methods override ...
//

	/**
	 * Create proposal with scope provider
	 * 
	 * @param crossReference
	 * @param contentAssistContext
	 * @param acceptor
	 */
	protected void completeUsingScopeProvider(CrossReference crossReference, ContentAssistContext contentAssistContext,
												ICompletionProposalAcceptor acceptor) {
		
		EReference target = GrammarUtil.getReference(crossReference);
		if(target == null){
			return;
		}
		
		//Request elements to the scope provider
		EObject currentModelElement = contentAssistContext.getCurrentModel();
		IScope scope = scopeProvider.getScope(currentModelElement, target);
		for (IEObjectDescription scopeElement : scope.getAllContents()) {

			//Get element and resolve proxy if needed
			EObject object = scopeElement.getEObjectOrProxy();
			if (object.eIsProxy()) {
				object = EcoreUtil.resolve(object, currentModelElement.eResource());
			}

			//Create new proposal
			String label = getLabelProvider().getText(object);
			if(label == null || label.equals("")){
				label = scopeElement.getName();
			}
			ICompletionProposal completionProposal = createCompletionProposal(scopeElement.getName(),
					getLabelProvider().getText(object), null, contentAssistContext);

			//Register proposal
			acceptor.accept(completionProposal);
		}
	}
}


Thanks Again.
P. Palau
Previous Topic:help with Xdoc
Next Topic:cross references and name spaces
Goto Forum:
  


Current Time: Thu Jul 10 04:30:04 EDT 2025

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

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

Back to the top