Import generation in model file [message #1758794] |
Mon, 03 April 2017 04:47  |
Eclipse User |
|
|
|
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 #1759517 is a reply to message #1758863] |
Wed, 12 April 2017 09:42   |
Eclipse User |
|
|
|
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 #1759525 is a reply to message #1759521] |
Wed, 12 April 2017 10:40   |
Eclipse User |
|
|
|
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)
}
}
|
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.07375 seconds