Import generation in model file [message #1758794] |
Mon, 03 April 2017 08:47 |
Akira Tanaka 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 |
|
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 #1759517 is a reply to message #1758863] |
Wed, 12 April 2017 13:42 |
Akira Tanaka 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 #1759525 is a reply to message #1759521] |
Wed, 12 April 2017 14:40 |
|
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
Day Job: https://www.everest-systems.com
|
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.04809 seconds