Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Import generation in model file
Import generation in model file [message #1758794] Mon, 03 April 2017 08:47 Go to next message
Akira Tanaka is currently offline Akira TanakaFriend
Messages: 98
Registered: March 2010
Member
Dear Xtext experts,

I asked the following question before:

Cross reference, SimpleNameProvider, and Package issue
https://www.eclipse.org/forums/index.php/t/1084934/

It seemed fine, but eventually I was faced to difficult situations (unexpected side effects, which is hard to explain here). Therefore, I switched to focusing on "import generation." Main reference was:

autoimport with Xbase 2.4
https://www.eclipse.org/forums/index.php/t/487230/

I followed the process (again based on domain model example) and created the following.

First, modified example domainmodel grammar:
...
Feature:
	Property | CrossReference | Operation;

Property:
	name=ValidID ':' type=JvmTypeReference;
	
CrossReference:
	'ref' name=ValidID ':' type=[Entity|QualifiedName]
;
...

Modified inferrer (no modification regarding name provider):
...
// for cross references we create a field
CrossReference : {
	if (f.type?.name == null) return;
	members += f.toField(f.name, f.type.fullyQualifiedName.toString(".").typeRef)
}
...

Then created the following class:
package org.eclipse.xtext.example.domainmodel.scoping;

import java.util.ArrayList;
import java.util.List;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.scoping.impl.ImportNormalizer;
import org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider;

public class DomainmodelImportedNamespaceAwareLocalScopeProvider extends ImportedNamespaceAwareLocalScopeProvider 
{
    static final ImportNormalizer modelImport1 = new ImportNormalizer(QualifiedName.create("com","example","domain","model","ordering"), true, false);
    static final ImportNormalizer modelImport2 = new ImportNormalizer(QualifiedName.create("java","lang"), true, false);
    static List<ImportNormalizer> modelImportList = new ArrayList<ImportNormalizer>();
    static 
    {
	    modelImportList.add(modelImport1);
	    modelImportList.add(modelImport2);
    }

    @Override
	  protected List<ImportNormalizer> getImplicitImports(boolean ignoreCase) {
	    return modelImportList;
	  }
}

And modified RuntimeModule (added the following code):
	@Override
	public void configureIScopeProviderDelegate(com.google.inject.Binder binder) {
		binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class)
			.annotatedWith(Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE))
			.to(org.eclipse.xtext.example.domainmodel.scoping.DomainmodelImportedNamespaceAwareLocalScopeProvider.class);
	}


The result is:
With the following models ---
test1.dmodel:
package com.example.domain.model.ordering {
	
	entity Customer {
		name: String
	}
}

test2.dmodel
package com.example.domain.model.customer_management {
	
	entity Employee {
		name : String
		ref responsible_customer : Customer
	}
}

Java code was successfully generated including necessary imports like below.
package com.example.domain.model.customer_management;

import com.example.domain.model.ordering.Customer;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;

@SuppressWarnings("all")
public class Employee {
  public Employee() {
  }
  
  public Employee(final Procedure1<Employee> initializer) {
    initializer.apply(this);
  }
  
  private String name;
  
  public String getName() {
    return this.name;
  }
  
  public void setName(final String name) {
    this.name = name;
  }
  
  private Customer responsible_customer;
  
  @Override
  public String toString() {
    String result = new ToStringBuilder(this).addAllFields().toString();
    return result;
  }
}


In addition to above, I would like to see "import" statement generated in model files, like the case when JvmTypeReference is used. Could you give me a pointer or sample to the class/method that is used to generate "import" statement into model?

Thank you for your help in advance.
Akira
Re: Import generation in model file [message #1758796 is a reply to message #1758794] Mon, 03 April 2017 09:06 Go to previous messageGo to next message
Karsten Thoms is currently offline Karsten ThomsFriend
Messages: 762
Registered: July 2009
Location: Dortmund, Germany
Senior Member

I'm not getting what you mean with "model" here. You are inferring a field, and the appropriate field gets generated to the inferred Java class "Employee" here. The import for "Customer" is generated. So where do you expect the import statement to be?

The XbaseCompiler will use org.eclipse.xtext.xbase.compiler.ImportManager to collect the imported type names and will generate the import statements for all types that are not in the same package as the inferred type.

Is this what you are searching for?
Re: Import generation in model file [message #1758800 is a reply to message #1758796] Mon, 03 April 2017 09:44 Go to previous messageGo to next message
Akira Tanaka is currently offline Akira TanakaFriend
Messages: 98
Registered: March 2010
Member
Thank you for the response.

With the current domain model example project, since type of Property is defined as JvmTypeReference, if you use control + space and choose some (not all, I know) type, import statement is generated in the model file (like below (not a good example though)).
import java.util.AbstractList.ListItr

package A {
	entity X {
		listItr : ListItr
	}
}


So, in addition to generating imports in Java code, I would like to see e.g. test2.dmodel (this is "model" I meant) to become (something like): <import statement added>
import com.example.domain.model.ordering.Customer
	
package com.example.domain.model.customer_management {

	entity Employee {
		name : String
		ref responsible_customer : Customer
	}
}


I hoe you understand my question. Is this not possible?

Akira
Re: Import generation in model file [message #1758840 is a reply to message #1758800] Mon, 03 April 2017 16:04 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
What do you mean by import statements being generated ?

What should trigger the generation

Are are you asking how to get implicit imports done with xbase


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Import generation in model file [message #1758842 is a reply to message #1758840] Mon, 03 April 2017 16:22 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Or are you looking for this code and or a nonxbase version of https://github.com/eclipse/xtext-eclipse/blob/9dba137b5af90c0ad8422f12ec5a8627631161b3/org.eclipse.xtext.xbase.ui/src/org/eclipse/xtext/xbase/ui/contentassist/ImportingTypesProposalProvider.java

E.g. As described here

https://www.eclipse.org/forums/index.php/t/352899/


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Import generation in model file [message #1758856 is a reply to message #1758840] Mon, 03 April 2017 20:30 Go to previous messageGo to next message
Karsten Thoms is currently offline Karsten ThomsFriend
Messages: 762
Registered: July 2009
Location: Dortmund, Germany
Senior Member

You may have a look at
https://github.com/eclipse/xtext-eclipse/blob/master/org.eclipse.xtext.xbase.ui/src/org/eclipse/xtext/xbase/ui/contentassist/ImportingTypesProposalProvider.java

This is the proposal provider that adds imports for proposed JVM Types.

Re: Import generation in model file [message #1758860 is a reply to message #1758840] Mon, 03 April 2017 21:41 Go to previous messageGo to next message
Akira Tanaka is currently offline Akira TanakaFriend
Messages: 98
Registered: March 2010
Member
Christian Dietrich wrote on Mon, 03 April 2017 12:04

What do you mean by import statements being generated ?


<= It's about generating "import com.example.domain.model.ordering.Customer" and inserting this into test2.dmodel, when you choose a type from candidate list shown by content assist.

Christian Dietrich wrote on Mon, 03 April 2017 12:04

What should trigger the generation


<= Probably by content assist mechanism

Christian Dietrich wrote on Mon, 03 April 2017 12:04

Are are you asking how to get implicit imports done with xbase


<= Yes, I am asking a way to achieve this for xbase based Xtext grammar case.
Re: Import generation in model file [message #1758862 is a reply to message #1758842] Mon, 03 April 2017 22:01 Go to previous messageGo to next message
Akira Tanaka is currently offline Akira TanakaFriend
Messages: 98
Registered: March 2010
Member
Thank you very much. I will look at this class.
Re: Import generation in model file [message #1758863 is a reply to message #1758856] Mon, 03 April 2017 22:02 Go to previous messageGo to next message
Akira Tanaka is currently offline Akira TanakaFriend
Messages: 98
Registered: March 2010
Member
Thank you very much. I will look at this class.
Re: Import generation in model file [message #1759517 is a reply to message #1758863] Wed, 12 April 2017 13:42 Go to previous messageGo to next message
Akira Tanaka is currently offline Akira TanakaFriend
Messages: 98
Registered: March 2010
Member
Hello Again,

I looked at around ImportingTypesProposalProvider, but still could not make it work.

I guess I need to do the following.
1) Extend ImportingTypesProposalProvider e.g. as DomainmodelImportingTypesProposalProvider to ui.contentassist, and give some modifications.
2) Modify DomainmodelProposalProvider to include "completeCrossReference_Type" like below.
	override completeCrossReference_Type(EObject model, Assignment assignment, ContentAssistContext context,ICompletionProposalAcceptor acceptor) {
		var crossReference = assignment.getTerminal() as CrossReference
		lookupCrossReference(crossReference, context, acceptor)
	}

and, 3) Add the bindings like below.
@FinalFieldsConstructor
class DomainmodelUiModule extends AbstractModelUiModule {
	def Class<? extends XbaseProposalProvider> bindXbaseProposalProvider() {
		return DomainmodelProposalProvider
	}
	override Class<? extends ITypesProposalProvider> bindITypesProposalProvider() {
		return DomainmodelImportingTypesProposalProvider
	} 	
}

In addition to several previous forum discussions, I looked at Jnario and Spray code, but their cases/grammars are different, and I would prefer simpler examples. Do you have any recommended open references?
Re: Import generation in model file [message #1759521 is a reply to message #1759517] Wed, 12 April 2017 13:58 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
sorry i dont understand this. in the domain model example this works out of the box
=> you dont need to do anything.

thus my question from before: do you use xbase or not?
is it a xbase reference you are talking about or not.
if not can you share a SMALL example grammar e.g. based on the domain model example


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Import generation in model file [message #1759525 is a reply to message #1759521] Wed, 12 April 2017 14:40 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
what i would have expected is:

copy and paste and adapt (make independent of JvmDeclaredType) of FQNImporter and FQNShortener

and then

class DomainmodelProposalProvider extends AbstractDomainmodelProposalProvider {

	@Inject
	private RewritableImportSection.Factory importSectionFactory;

	@Inject
	private ReplaceConverter replaceConverter;

	@Inject
	private IScopeProvider scopeProvider;

	def IReplacementTextApplier createTextApplier(ContentAssistContext context, IScope typeScope,
		IQualifiedNameConverter qualifiedNameConverter, IValueConverter<String> valueConverter) {
		if (EcoreUtil2.getContainerOfType(context.getCurrentModel(), XImportSection) !== null)
			return null;
		return new FQNImporter(context.getResource(), context.getViewer(), typeScope, qualifiedNameConverter,
			valueConverter, importSectionFactory, replaceConverter);
	}

	override protected lookupCrossReference(CrossReference crossReference, EReference reference,
		ContentAssistContext contentAssistContext, ICompletionProposalAcceptor acceptor,
		Predicate<IEObjectDescription> filter) {
			super.lookupCrossReference(crossReference, reference, contentAssistContext,
				new ICompletionProposalAcceptor() {

					override accept(ICompletionProposal proposal) {
						if (proposal instanceof ConfigurableCompletionProposal) {
							proposal.textApplier = createTextApplier(
								contentAssistContext,
								scopeProvider.getScope(contentAssistContext.currentModel, reference),
								qualifiedNameConverter,
								qualifiedNameValueConverter
							)
						}
						acceptor.accept(proposal)
					}

					override canAcceptMoreProposals() {
						acceptor.canAcceptMoreProposals()
					}

				}, filter)
		}

	}


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Import generation in model file [message #1759526 is a reply to message #1759521] Wed, 12 April 2017 14:48 Go to previous messageGo to next message
Akira Tanaka is currently offline Akira TanakaFriend
Messages: 98
Registered: March 2010
Member
Thank you for quick response. I thought I provided everything already, but here it is. And, yes I use xbase.

The grammar
grammar org.eclipse.xtext.example.domainmodel.Domainmodel with org.eclipse.xtext.xbase.Xbase
generate domainmodel "http://www.xtext.org/example/Domainmodel"

DomainModel:
	importSection=XImportSection?
	elements+=AbstractElement*;
AbstractElement:
	PackageDeclaration | Entity;
PackageDeclaration:
	'package' name=QualifiedName '{'
		elements+=AbstractElement*
	'}';
Entity:
	'entity' name=ValidID ('extends' superType=JvmTypeReference)? '{'
		features+=Feature*
	'}';
Feature:
	Property | CrossReference | Operation;
Property:
	name=ValidID ':' type=JvmTypeReference;	
CrossReference:
	'ref' name=ValidID ':' type=[Entity|QualifiedName]
;
Operation:
	'op' name=ValidID '(' (params+=FullJvmFormalParameter (',' params+=FullJvmFormalParameter)*)? ')' (':' type=JvmTypeReference)? 
		body=XBlockExpression;

Please see my first message regarding other codes. With this settings, I am able to implement cross reference including generating import statements into Java code, but I am not able to generate import statement into e.g. sample.dmodel file. Import statements are generated by default if I use type=JvmTypeReference, but it is not the case with cross reference (type=[Entity|QualifiedName]) case. This is what I like to achieve using the basic domainmodel example.
Re: Import generation in model file [message #1759527 is a reply to message #1759526] Wed, 12 April 2017 14:52 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
see my previous post. it should make clear what you have to do

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Import generation in model file [message #1760079 is a reply to message #1759527] Sat, 22 April 2017 00:57 Go to previous messageGo to next message
Akira Tanaka is currently offline Akira TanakaFriend
Messages: 98
Registered: March 2010
Member
Thank you very much. It took some time to figure out what to do, but now it's working. Here is what I did.

1) scoping: the same as before

2) content assist:
- added DomainmodelProposalProvider. Used completeProperty_Type(...) as an entry point.
- added DomainmodelImportingTypesProposalProvider class extending ImportingTypesProposalProvider, modified it to handle qualified name to suit our needs, and modified addImport part as importSection.addImport(qualifiedName.toString()).
- added bindings (as I described before).

I still have a small issue. Import statements are dynamically generated into model (e.g. sample.dmodel), but they are marked with "... is never used" yellow-colored warnings. Do you have any idea on what's caused those warnings?
Re: Import generation in model file [message #1760094 is a reply to message #1760079] Sat, 22 April 2017 10:23 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
The import validation checks only usages in xbase and thus will find yours as unused .

have a look at checkImports in the vslidator


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Import generation in model file [message #1761075 is a reply to message #1760094] Sat, 06 May 2017 05:39 Go to previous message
Akira Tanaka is currently offline Akira TanakaFriend
Messages: 98
Registered: March 2010
Member
Hello Christian san,

Thank you very much for your help. Resulting source code are at https://github.com/atanaka/DomainmodelWithCrossReference.
Previous Topic:Invalid synchronization of resources
Next Topic:[SOLVED] Invalid injection for JavaElementDelegateAdapter
Goto Forum:
  


Current Time: Thu Mar 28 12:30:08 GMT 2024

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

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

Back to the top