在我的模型中,我有更多的對象是以後生成的Java類。 例如在一個文件中被定義如何在Xtext中生成方法時避免JvmParameterizedTypeReference:java.util.List <JvmUnknownTypeReference:A>?
Object A {
operation getList B
}
而在其他文件中:
Object B {
operation getList A
}
1)從該2個接口應生成:
interface A {
java.util.List<B> getListOfBs();
}
interface B {
java.util.List<A> getListOfAs();
}
2)相反,它是新像這樣產生的:
interface A {
/* java.util.List<B> */ Object getListOfBs();
}
interface B {
/* java.util.List<A> */ Object getListOfAs();
}
只有當我在Eclipse中運行Project - > Clean ...時纔會發生這種情況。
我改變了我的模型中的東西,並保存它,一切都生成好,它看起來像第一個例子。 當我調試我的推理者時,我注意到創建方法的返回類型被定義爲JvmParameterizedTypeReference:java.util.List < JvmUnknownTypeReference:A >。
有沒有一種方法可以在Eclipse中清理後生成類?
編輯 我現在有一個重複我的問題的例子。真的需要有這麼多的模型文件,否則一切都運行正常。 我使用默認值創建了新的Xtext項目。我XTEXT文件:
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.xbase.Xbase
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
ModelDomain:
SubPackageDeclaration
elements+=DataModelItem*;
SubPackageDeclaration:
'subPackage' subPackageName=ID;
DataModelItem:
DataType | DataObject | DataEnum;
DataType:
'DataType' name=ID type=JvmParameterizedTypeReference;
DataObject:
'DataObject' name=ID '{'
('lists' '{'
(lists+=DataAttribute)*
'}')?
'}';
DataEnum:
'DataEnum' name=ID '{'
values+=ID (',' values+=ID)*
'}';
DataAttribute:
(transient?='transient')? type=[DataModelItem|QualifiedName] name=ID;
和推斷器:
package org.xtext.example.mydsl.jvmmodel
import com.google.inject.Inject
import org.eclipse.xtext.common.types.JvmTypeReference
import org.eclipse.xtext.common.types.TypesFactory
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.xtext.example.mydsl.myDsl.DataEnum
import org.xtext.example.mydsl.myDsl.DataModelItem
import org.xtext.example.mydsl.myDsl.DataObject
import org.xtext.example.mydsl.myDsl.DataType
import org.xtext.example.mydsl.myDsl.SubPackageDeclaration
class MyDslJvmModelInferrer extends AbstractModelInferrer {
@Inject extension JvmTypesBuilder
@Inject private TypesFactory typesFactory
def dispatch void infer(DataEnum dataEnum, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
var packageName = ""
if (dataEnum.eContainer != null && dataEnum.eContainer instanceof SubPackageDeclaration) {
var implDec = (dataEnum.eContainer as SubPackageDeclaration)
packageName = "data.model." + implDec.subPackageName
}
val qualifiedName = packageName + "." + dataEnum.name.toFirstUpper
acceptor.accept(
dataEnum.toEnumerationType(qualifiedName) [
for (value : dataEnum.values) {
val jvmLiteral = typesFactory.createJvmEnumerationLiteral
jvmLiteral.simpleName = value
jvmLiteral.^static = true
var t1 = typesFactory.createJvmParameterizedTypeReference
t1.type = it
jvmLiteral.type = t1
members += jvmLiteral
}
])
}
def dispatch void infer(DataObject dataObject, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
var packageName = ""
if (dataObject.eContainer != null && dataObject.eContainer instanceof SubPackageDeclaration) {
var implDec = (dataObject.eContainer as SubPackageDeclaration)
packageName = "data.model." + implDec.subPackageName
}
val qualifiedName = packageName + "." + dataObject.name.toFirstUpper
acceptor.accept(
dataObject.toInterface(qualifiedName) [
superTypes += dataObject.newTypeRef("data.model.core.IDataObject")
for (list : dataObject.lists) {
val JvmTypeReference ^void = dataObject.newTypeRef(Void.TYPE)
val JvmTypeReference listTypeRef = convertToJvmType(list.type)
if (listTypeRef != null && !isPreIndexingPhase) {
val removeMethod = list.toMethod("remove" + list.name.toFirstUpper, ^void) [
parameters += list.toParameter(list.name, listTypeRef)
]
members += removeMethod
removeMethod.setAbstract(true);
val returnType = dataObject.newTypeRef("java.util.List", listTypeRef)
val allMethod = list.toMethod("get" + list.name.toFirstUpper + "List", returnType)[]
allMethod.setAbstract(true);
members += allMethod
}
}
val denyLoading = dataObject.toMethod("denyLoading", dataObject.newTypeRef(Void.TYPE))[]
denyLoading.setAbstract(true);
members += denyLoading
])
}
def public JvmTypeReference convertToJvmType(DataModelItem modelItem) {
var JvmTypeReference typeRef
if (modelItem instanceof DataType) {
var typeData = (modelItem as DataType)
typeRef = typeData.type.cloneWithProxies
} else if (modelItem instanceof DataEnum) {
var typeDec = (modelItem.eContainer as SubPackageDeclaration)
var typePackageName = "data.model." + typeDec.subPackageName
val typeData = modelItem as DataEnum
typeRef = typeData.newTypeRef(typePackageName + "." + typeData.name)
} else if (modelItem.eContainer != null) {
var typeDec = (modelItem.eContainer as SubPackageDeclaration)
var typePackageName = "data.model." + typeDec.subPackageName
var typeQName = typePackageName + "." + modelItem.name
typeRef = modelItem.newTypeRef(typeQName)
}
return typeRef
}
}
然後,我有這6個看MyDSL文件:
1. address.mydsl
subPackage address DataObject PhoneNumber { lists { PhoneNumberType types } } DataObject Contact { lists { PhoneNumber phoneNumber } } DataObject Address { lists { PhoneNumber phoneNumber } } DataEnum PhoneNumberType { BUSINESS_PHONE , BUSINESS_FAX , BUSINESS_MOBILE , HOME_PHONE , HOME_MOBILE , HOME_FAX } DataEnum Gender { FEMALE , MALE }
2. asset.mydsl
subPackage asset DataObject Asset { lists { LiabilityCase liabilityCase} } DataObject VehicleEquipment { lists { Address address } } DataObject LiabilityCase { } DataObject AssetVehicle { lists { VehicleEquipment serial VehicleEquipment extra } } DataObject Tires { } DataObject RentalObject { lists { Asset vehicle Asset mob Asset prop Asset estate Asset asset } } DataEnum AssetCondition { NEW , USED , DEMO } DataEnum VehicleColorType { STANDARD , PEARL_EFFECT , METALLIC , SPECIAL } DataEnum TiresType { SUMMER , WINTER } DataEnum AssetClass { VEHICLE , MOB , PROPERTY , ESTATE }
3. businessPartner.mydsl
subPackage businesspartner DataEnum BusinessPartnerType { INDIVIDUAL , ORGANISATION } DataObject BusinessPartner { lists { Address address Contact contact BpTransactions transaction BpAdvisorRelation advisor } } DataObject BpRiskParameters { } DataObject BpTransactions { } DataObject BalanceDetails { } DataObject BpAdvisorRelation { } DataEnum AdvisorType { ADVISOR , ADVISOR_BO , ADMINISTRATOR }
4. invoice.mydsl
subPackage invoice DataObject Invoice{ lists { Receipt receipt } } DataObject Receipt { lists { InvoiceItem item } } DataObject ReceiptFleet { } DataObject InvoiceItem{ } DataEnum InvoiceCategory { OBJECT, SERVICE ,INVOICES } DataEnum InvoiceType { INCOMING, OUTGOING } DataEnum InvoiceStatus { OPEN, PARTIALLY_COMPLETE, COMPLETE } DataEnum ItemUnit { UNIT, PALETTE, DOZEN, LITRE } DataEnum ItemIdType { LICENSE_PLATE, CARD_NUMBER, OBJECT_ID }
5. securities.mydsl
subPackage securities DataObject Securities {} DataEnum SecuritiesType {PARTNER_APPLICANT, GUARANTOR,SOMETHING_ELSE}
6. types.mydsl
subPackage types DataType String java.lang.String DataType Integer java.lang.Integer DataType Double java.lang.Double DataType Date java.util.Date DataType Boolean java.lang.Boolean DataType Void java.lang.Void
生成接口擴展爲data.model.core.IDataObject
。這個接口沒有方法。後在Eclipse 乾淨行動,我可以看到getPhoneNumberList方法作爲
public abstract /* List<data.model.address.PhoneNumber> */Object getPhoneNumberList();
以及其他方法產生,但其他都OK。
我用Xtext 2.5和2.3測試了它,結果相同。
我得到的控制檯錯誤說:
2 [Worker-4] ERROR org.eclipse.xtext.common.types.access.jdt.JdtTypeProvider - [Working copy] PhoneNumber.java [in data.model.address [in src-gen [in test]]] does not exist
Java Model Exception: Java Model Status [[Working copy] PhoneNumber.java [in data.model.address [in src-gen [in test]]] does not exist]
,但我不知道如何解決它。
我不能在這個項目中有任何類我只需要接口。但即使當我用myObject.toInterface嘗試它時,我仍然有同樣的問題。 有趣的是,當我在更簡單的項目中執行操作時,就像我的示例一樣,它工作正常。然後我在調試中看到返回類型: JvmParameterizedTypeReference:java.util.List –
borism
嗨,如果你有時間,我更新了我的問題並添加了整個示例。 – borism
感謝您澄清問題。我更新了答案。 –