package org.xtest.jvmmodel; import java.util.Iterator; import org.eclipse.emf.ecore.EObject; import org.eclipse.xtend.core.jvmmodel.XtendJvmModelInferrer; import org.eclipse.xtend.core.xtend.XtendParameter; import org.eclipse.xtext.common.types.JvmFormalParameter; import org.eclipse.xtext.common.types.JvmGenericType; import org.eclipse.xtext.common.types.JvmOperation; import org.eclipse.xtext.common.types.JvmTypeReference; import org.eclipse.xtext.common.types.JvmVisibility; import org.eclipse.xtext.common.types.TypesFactory; import org.eclipse.xtext.common.types.util.TypeReferences; import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor; import org.eclipse.xtext.xbase.jvmmodel.IJvmModelAssociator; import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder; import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; import org.eclipse.xtext.xbase.typing.ITypeProvider; import org.xtest.xTest.XMethodDef; import org.xtest.xTest.impl.BodyImplCustom; import com.google.common.collect.Iterables; import com.google.inject.Inject; /** * Infers a JVM Model (classes, methods, etc.) from the xtest model. * * Each Xtest file is a class. Each method def is a method of that class. The rest is interpreted. */ @SuppressWarnings("all") public class XTestJvmModelInferrer extends XtendJvmModelInferrer { @Inject private IJvmModelAssociator associator; @Inject private JvmTypesBuilder builder; @Inject private ITypeProvider computer; @Inject private TypesFactory factory; @Inject private TypeReferences typeRefs; @Override public void infer(EObject e, IJvmDeclaredTypeAcceptor acceptor, boolean preIndexingPhase) { if (e instanceof BodyImplCustom) { BodyImplCustom body = (BodyImplCustom) e; JvmGenericType type = factory.createJvmGenericType(); type.setSimpleName(body.getTypeName()); type.setVisibility(JvmVisibility.PUBLIC); associator.associatePrimary(body, type); acceptor.accept(type).initializeLater(typeBuilder(body)); } } protected Iterable<XMethodDef> getMethodDefs(final BodyImplCustom body) { Iterable<EObject> contents = new Iterable<EObject>() { @Override public Iterator<EObject> iterator() { return body.eAllContents(); } }; Iterable<XMethodDef> defs = Iterables.filter(contents, XMethodDef.class); return defs; } protected void translate(JvmGenericType type, final XMethodDef def) { if (def.getName() != null) { JvmOperation op = factory.createJvmOperation(); type.getMembers().add(op); op.setSimpleName(def.getName()); op.setVisibility(JvmVisibility.PUBLIC); JvmTypeReference returnType = def.getReturnType(); returnType = returnType == null ? getTypeProxy(op) : builder .cloneWithProxies(returnType); op.setReturnType(returnType); op.setStatic(def.isStatic()); String documentation = builder.getDocumentation(def); builder.setDocumentation(op, documentation); for (XtendParameter param : def.getParameters()) { translateParameter(op, param); } copyAndFixTypeParameters(def.getTypeParameters(), op); builder.setBody(op, def.getExpression()); associator.associatePrimary(def, op); } } private void initializeType(final BodyImplCustom body, JvmGenericType type) { builder.setDocumentation(type, builder.getDocumentation(body)); for (final XMethodDef def : getMethodDefs(body)) { translate(type, def); } } private void translate(JvmOperation op, JvmFormalParameter param) { op.getParameters().add(builder.cloneWithProxies(param)); associator.associatePrimary(op, param); } private Procedure1<JvmGenericType> typeBuilder(final BodyImplCustom body) { return new Procedure1<JvmGenericType>() { public void apply(JvmGenericType type) { initializeType(body, type); } }; }; }