|
|
Re: Type Resolution within XBlockExpression [message #1753506 is a reply to message #1753505] |
Tue, 07 February 2017 10:31 |
Akira Tanaka Messages: 98 Registered: March 2010 |
Member |
|
|
Thank you for the response. Here are the files.
Grammar:
/*******************************************************************************
* Copyright (c) 2009 itemis AG (http://www.itemis.eu) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
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=JvmParameterizedTypeReference)? '{'
features+=Feature*
'}';
Feature:
Property | Operation;
Property:
PropertyTypeA | PropertyTypeB;
PropertyTypeA:
'type_a' name=ValidID ':' type=JvmTypeReference;
PropertyTypeB:
'type_b' name=ValidID ':' type=[Entity|ValidID];
Operation:
'op' name=ValidID '(' (params+=FullJvmFormalParameter (',' params+=FullJvmFormalParameter)*)? ')' (':' type=JvmTypeReference)?
body=XBlockExpression;
Inferrer
package org.eclipse.xtext.example.domainmodel.jvmmodel
import com.google.inject.Inject
import org.eclipse.xtext.example.domainmodel.domainmodel.Entity
import org.eclipse.xtext.example.domainmodel.domainmodel.Operation
import org.eclipse.xtext.example.domainmodel.domainmodel.Property
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1
import org.eclipse.xtext.example.domainmodel.domainmodel.PropertyTypeA
import org.eclipse.xtext.example.domainmodel.domainmodel.PropertyTypeB
class DomainmodelJvmModelInferrer extends AbstractModelInferrer {
@Inject extension JvmTypesBuilder
@Inject extension IQualifiedNameProvider
def dispatch infer(Entity entity, extension IJvmDeclaredTypeAcceptor acceptor, boolean prelinkingPhase) {
accept(entity.toClass( entity.fullyQualifiedName )).initializeLater [
documentation = entity.documentation
if (entity.superType != null)
superTypes += entity.superType.cloneWithProxies
// let's add a default constructor
members += entity.toConstructor []
// and one which can be called with a lambda for initialization.
val procedureType = typeRef(Procedure1, typeRef(it)) /* Procedure<MyEntity> */
members += entity.toConstructor [
parameters += entity.toParameter("initializer", procedureType)
// here we implement the body using black box Java code.
body = '''
initializer.apply(this);
'''
]
// now let's go over the features
for ( f : entity.features ) {
switch f {
// for properties we create a field, a getter and a setter
Property : {
if (f instanceof PropertyTypeA) {
members += f.toField(f.name, f.type)
members += f.toGetter(f.name, f.type)
members += f.toSetter(f.name, f.type)
}
else if (f instanceof PropertyTypeB) {
val String name = f.type?.name
members += f.toField(f.name, name.typeRef)
members += f.toGetter(f.name, name.typeRef)
members += f.toSetter(f.name, name.typeRef)
}
}
// operations are mapped to methods
Operation : {
members += f.toMethod(f.name, f.type ?: inferredType) [
documentation = f.documentation
for (p : f.params) {
parameters += p.toParameter(p.name, p.parameterType)
}
// here the body is implemented using a user expression.
// Note that by doing this we set the expression into the context of this method,
// The parameters, 'this' and all the members of this method will be visible for the expression.
body = f.body
]
}
}
}
// finally we want to have a nice toString methods.
members += entity.toToStringMethod(it)
]
}
}
test model
package demo {
entity Company {
type_a name : String
}
entity Person {
type_a name : String
type_b worksfor : Company
op init(String name, Company abc){
this.name = name
this.worksfor = abc
}
}
}
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.04540 seconds