/******************************************************************************* * Copyright (c) 2010-2012, Mark Czotter, Istvan Rath and Daniel Varro * 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 * * Contributors: * Mark Czotter - initial API and implementation *******************************************************************************/ package org.eclipse.incquery.tooling.core.generator.types; import org.eclipse.emf.codegen.ecore.genmodel.GenClass; import org.eclipse.emf.codegen.ecore.genmodel.GenPackage; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.incquery.patternlanguage.emf.types.EMFPatternTypeProvider; import org.eclipse.incquery.patternlanguage.patternLanguage.PatternBody; import org.eclipse.incquery.patternlanguage.patternLanguage.Variable; import org.eclipse.incquery.tooling.core.generator.builder.GeneratorIssueCodes; import org.eclipse.incquery.tooling.core.generator.builder.IErrorFeedback; import org.eclipse.incquery.tooling.core.generator.genmodel.IEiqGenmodelProvider; import org.eclipse.xtext.common.types.JvmTypeReference; import org.eclipse.xtext.common.types.util.Primitives; import org.eclipse.xtext.common.types.util.TypeReferences; import org.eclipse.xtext.diagnostics.Severity; import com.google.inject.Inject; import com.google.inject.Singleton; /** * An extension of the {@link EMFPatternTypeProvider}, which can use the genmodel informations as well, if it is * present. The main logic for the type inference is implemented in the {@link EMFPatternTypeProvider}. */ @Singleton @SuppressWarnings("restriction") public class GenModelBasedTypeProvider extends EMFPatternTypeProvider { @Inject private IEiqGenmodelProvider genModelProvider; @Inject private IErrorFeedback errorFeedback; @Inject private TypeReferences typeReferences; @Inject private Primitives primitives; @Override protected JvmTypeReference getTypeReferenceForVariableWithEClassifier(EClassifier classifier, Variable variable) { JvmTypeReference typeReference = super.getTypeReferenceForVariableWithEClassifier(classifier, variable); if (typeReference == null && classifier != null) { EPackage ePackage = classifier.getEPackage(); if (ePackage != null) { GenPackage genPackage = genModelProvider.findGenPackage(variable, ePackage); if (genPackage != null) { typeReference = resolveTypeReference(genPackage, classifier, variable); } } } return typeReference; } /** * Resolves the {@link Variable} using information from the {@link GenPackage}. Tries to find an appropriate * {@link GenClass} for the {@link EClassifier}. If one is found, then returns a {@link JvmTypeReference} for it's * qualified interface name. * * @param genPackage * @param classifier * @param variable * @return */ private JvmTypeReference resolveTypeReference(GenPackage genPackage, EClassifier classifier, Variable variable) { GenClass genClass = findGenClass(genPackage, classifier); if (genClass != null) { JvmTypeReference typeReference = getTypeReferenceForTypeName(genClass.getQualifiedInterfaceName(), variable); if (typeReference == null) { EObject context = variable; if (variable.eContainer() instanceof PatternBody && variable.getReferences().size() > 0) { context = variable.getReferences().get(0); } errorFeedback .reportError( context, String.format( "Cannot resolve corresponding Java type for variable %s. Are the required bundle dependencies set?", variable.getName()), GeneratorIssueCodes.INVALID_TYPEREF_CODE, Severity.WARNING, IErrorFeedback.JVMINFERENCE_ERROR_TYPE); } return typeReference; } return null; } private GenClass findGenClass(GenPackage genPackage, EClassifier classifier) { for (GenClass genClass : genPackage.getGenClasses()) { if (classifier.equals(genClass.getEcoreClassifier())) { return genClass; } } return null; } private JvmTypeReference getTypeReferenceForTypeName(String typeName, Variable variable) { JvmTypeReference typeRef = typeReferences.getTypeForName(typeName, variable); return primitives.asWrapperTypeIfPrimitive(typeRef); } }