blob: 6b96e9d1712f060590d157732d90ca4304151db5 [file] [log] [blame]
/**
* Copyright (c) 2011-2012 Eclipse contributors 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
*/
package org.eclipse.emf.ecore.xcore.generator;
import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.codegen.ecore.genmodel.GenClass;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage;
import org.eclipse.emf.codegen.ecore.genmodel.GenOperation;
import org.eclipse.emf.codegen.ecore.genmodel.generator.GenBaseGeneratorAdapter;
import org.eclipse.emf.codegen.util.CodeGenUtil;
import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xcore.XClass;
import org.eclipse.emf.ecore.xcore.XClassifier;
import org.eclipse.emf.ecore.xcore.XDataType;
import org.eclipse.emf.ecore.xcore.XOperation;
import org.eclipse.emf.ecore.xcore.XPackage;
import org.eclipse.emf.ecore.xcore.XStructuralFeature;
import org.eclipse.emf.ecore.xcore.generator.XcoreAppendable;
import org.eclipse.emf.ecore.xcore.generator.XcoreGeneratorImpl;
import org.eclipse.emf.ecore.xcore.mappings.XClassMapping;
import org.eclipse.emf.ecore.xcore.mappings.XDataTypeMapping;
import org.eclipse.emf.ecore.xcore.mappings.XFeatureMapping;
import org.eclipse.emf.ecore.xcore.mappings.XOperationMapping;
import org.eclipse.emf.ecore.xcore.mappings.XcoreMapper;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmFormalParameter;
import org.eclipse.xtext.common.types.JvmOperation;
import org.eclipse.xtext.common.types.JvmType;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.generator.IFileSystemAccess;
import org.eclipse.xtext.generator.IGenerator;
import org.eclipse.xtext.linking.impl.XtextLinkingDiagnostic;
import org.eclipse.xtext.xbase.XBlockExpression;
import org.eclipse.xtext.xbase.compiler.XbaseCompiler;
import org.eclipse.xtext.xbase.compiler.output.ITreeAppendable;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
@SuppressWarnings("all")
public class XcoreGenerator implements IGenerator {
@Inject
@Extension
private XcoreMapper mappings;
@Inject
private XbaseCompiler compiler;
@Inject
private Provider<XcoreGeneratorImpl> xcoreGeneratorImplProvider;
public void generateBodyAnnotations(final XPackage pack) {
final LinkedHashMap<EObject, String> errors = this.getErrors(pack);
final HashSet<ETypedElement> processed = CollectionLiterals.<ETypedElement>newHashSet();
EList<XClassifier> _classifiers = pack.getClassifiers();
for (final XClassifier xClassifier : _classifiers) {
if ((xClassifier instanceof XDataType)) {
final XDataType xDataType = ((XDataType)xClassifier);
XDataTypeMapping _mapping = this.mappings.getMapping(xDataType);
final EDataType eDataType = _mapping.getEDataType();
final XBlockExpression createBody = xDataType.getCreateBody();
XDataTypeMapping _mapping_1 = this.mappings.getMapping(xDataType);
final JvmOperation creator = _mapping_1.getCreator();
if (((!Objects.equal(createBody, null)) && (!Objects.equal(creator, null)))) {
final XcoreAppendable appendable = this.createAppendable();
EList<JvmFormalParameter> _parameters = creator.getParameters();
JvmFormalParameter _get = _parameters.get(0);
appendable.declareVariable(_get, "it");
JvmTypeReference _returnType = creator.getReturnType();
Set<JvmTypeReference> _emptySet = Collections.<JvmTypeReference>emptySet();
this.compile(eDataType, "create", appendable, errors, createBody, _returnType, _emptySet);
}
final XBlockExpression convertBody = xDataType.getConvertBody();
XDataTypeMapping _mapping_2 = this.mappings.getMapping(xDataType);
final JvmOperation converter = _mapping_2.getConverter();
if (((!Objects.equal(convertBody, null)) && (!Objects.equal(converter, null)))) {
final XcoreAppendable appendable_1 = this.createAppendable();
EList<JvmFormalParameter> _parameters_1 = converter.getParameters();
JvmFormalParameter _get_1 = _parameters_1.get(0);
appendable_1.declareVariable(_get_1, "it");
JvmTypeReference _returnType_1 = converter.getReturnType();
Set<JvmTypeReference> _emptySet_1 = Collections.<JvmTypeReference>emptySet();
this.compile(eDataType, "convert", appendable_1, errors, convertBody, _returnType_1, _emptySet_1);
}
} else {
final XClass xClass = ((XClass) xClassifier);
XClassMapping _mapping_3 = this.mappings.getMapping(xClass);
final EClass eClass = _mapping_3.getEClass();
EList<EStructuralFeature> _eAllStructuralFeatures = eClass.getEAllStructuralFeatures();
for (final EStructuralFeature eStructuralFeature : _eAllStructuralFeatures) {
boolean _add = processed.add(eStructuralFeature);
if (_add) {
final XStructuralFeature xFeature = this.mappings.getXFeature(eStructuralFeature);
boolean _notEquals = (!Objects.equal(xFeature, null));
if (_notEquals) {
final XBlockExpression getBody = xFeature.getGetBody();
boolean _notEquals_1 = (!Objects.equal(getBody, null));
if (_notEquals_1) {
XFeatureMapping _mapping_4 = this.mappings.getMapping(xFeature);
final JvmOperation getter = _mapping_4.getGetter();
final XcoreAppendable appendable_2 = this.createAppendable();
JvmDeclaredType _declaringType = getter.getDeclaringType();
appendable_2.declareVariable(_declaringType, "this");
JvmDeclaredType _declaringType_1 = getter.getDeclaringType();
EList<JvmTypeReference> _superTypes = _declaringType_1.getSuperTypes();
final JvmTypeReference superType = IterableExtensions.<JvmTypeReference>head(_superTypes);
boolean _notEquals_2 = (!Objects.equal(superType, null));
if (_notEquals_2) {
JvmType _type = superType.getType();
appendable_2.declareVariable(_type, "super");
}
JvmTypeReference _returnType_2 = getter.getReturnType();
Set<JvmTypeReference> _emptySet_2 = Collections.<JvmTypeReference>emptySet();
this.compile(eStructuralFeature, "get", appendable_2, errors, getBody, _returnType_2, _emptySet_2);
}
}
}
}
EList<EOperation> _eAllOperations = eClass.getEAllOperations();
for (final EOperation eOperation : _eAllOperations) {
boolean _add_1 = processed.add(eOperation);
if (_add_1) {
final XOperation xOperation = this.mappings.getXOperation(eOperation);
boolean _notEquals_3 = (!Objects.equal(xOperation, null));
if (_notEquals_3) {
final XBlockExpression body = xOperation.getBody();
boolean _notEquals_4 = (!Objects.equal(body, null));
if (_notEquals_4) {
final XOperationMapping xOperationMapping = this.mappings.getMapping(xOperation);
final JvmOperation jvmOperation = xOperationMapping.getJvmOperation();
boolean _notEquals_5 = (!Objects.equal(jvmOperation, null));
if (_notEquals_5) {
final XcoreAppendable appendable_3 = this.createAppendable();
JvmDeclaredType declaringType = jvmOperation.getDeclaringType();
GenOperation _genOperation = xOperationMapping.getGenOperation();
GenClass _genClass = _genOperation.getGenClass();
boolean _isExternalInterface = _genClass.isExternalInterface();
if (_isExternalInterface) {
final EList<JvmTypeReference> superTypes = declaringType.getSuperTypes();
final JvmTypeReference effectiveTypeReference = IterableExtensions.<JvmTypeReference>head(superTypes);
boolean _notEquals_6 = (!Objects.equal(effectiveTypeReference, null));
if (_notEquals_6) {
JvmType _type_1 = effectiveTypeReference.getType();
appendable_3.declareVariable(_type_1, "this");
}
} else {
appendable_3.declareVariable(declaringType, "this");
EList<JvmTypeReference> _superTypes_1 = declaringType.getSuperTypes();
final JvmTypeReference superType_1 = IterableExtensions.<JvmTypeReference>head(_superTypes_1);
boolean _notEquals_7 = (!Objects.equal(superType_1, null));
if (_notEquals_7) {
JvmType _type_2 = superType_1.getType();
appendable_3.declareVariable(_type_2, "super");
}
}
EList<JvmFormalParameter> _parameters_2 = jvmOperation.getParameters();
for (final JvmFormalParameter parameter : _parameters_2) {
String _name = parameter.getName();
appendable_3.declareVariable(parameter, _name);
}
JvmTypeReference _returnType_3 = jvmOperation.getReturnType();
EList<JvmTypeReference> _exceptions = jvmOperation.getExceptions();
HashSet<JvmTypeReference> _hashSet = new HashSet<JvmTypeReference>(_exceptions);
this.compile(eOperation, "body", appendable_3, errors, body, _returnType_3, _hashSet);
}
}
}
}
}
}
}
}
@Override
public void doGenerate(final Resource resource, final IFileSystemAccess fsa) {
EList<EObject> _contents = resource.getContents();
EObject _head = IterableExtensions.<EObject>head(_contents);
this.generateBodyAnnotations(((XPackage) _head));
EList<EObject> _contents_1 = resource.getContents();
Iterable<GenModel> _filter = Iterables.<GenModel>filter(_contents_1, GenModel.class);
GenModel _head_1 = IterableExtensions.<GenModel>head(_filter);
this.generateGenModel(_head_1, fsa);
}
public void compile(final EModelElement target, final String key, final ITreeAppendable appendable, final Map<EObject, String> errors, final XBlockExpression body, final JvmTypeReference returnType, final Set<JvmTypeReference> exceptions) {
try {
Set<Map.Entry<EObject, String>> _entrySet = errors.entrySet();
for (final Map.Entry<EObject, String> error : _entrySet) {
EObject _key = error.getKey();
boolean _isAncestor = EcoreUtil.isAncestor(body, _key);
if (_isAncestor) {
String _value = error.getValue();
throw new RuntimeException(_value);
}
}
this.compiler.compile(body, appendable, returnType, exceptions);
String _string = appendable.toString();
String _extractBody = this.extractBody(_string);
EcoreUtil.setAnnotation(target, GenModelPackage.eNS_URI, key, _extractBody);
} catch (final Throwable _t) {
if (_t instanceof Throwable) {
final Throwable throwable = (Throwable)_t;
String _message = throwable.getMessage();
String _unicodeEscapeEncode = CodeGenUtil.unicodeEscapeEncode(_message);
String _plus = ("throw new <%java.lang.Error%>(\"Unresolved compilation problems: " + _unicodeEscapeEncode);
String _plus_1 = (_plus + "\");");
EcoreUtil.setAnnotation(target, GenModelPackage.eNS_URI, key, _plus_1);
} else {
throw Exceptions.sneakyThrow(_t);
}
}
}
public LinkedHashMap<EObject, String> getErrors(final XPackage xPackage) {
final LinkedHashMap<EObject, String> result = Maps.<EObject, String>newLinkedHashMap();
final Resource resource = xPackage.eResource();
EList<Resource.Diagnostic> _errors = resource.getErrors();
for (final Resource.Diagnostic diagnostic : _errors) {
if ((diagnostic instanceof XtextLinkingDiagnostic)) {
final URI uri = ((XtextLinkingDiagnostic)diagnostic).getUriToProblem();
boolean _notEquals = (!Objects.equal(uri, null));
if (_notEquals) {
String _fragment = uri.fragment();
final EObject eObject = resource.getEObject(_fragment);
boolean _notEquals_1 = (!Objects.equal(eObject, null));
if (_notEquals_1) {
String _message = ((XtextLinkingDiagnostic)diagnostic).getMessage();
result.put(eObject, _message);
}
}
}
}
return result;
}
public XcoreAppendable createAppendable() {
return new XcoreAppendable();
}
public String extractBody(final String body) {
String _xblockexpression = null;
{
String _xifexpression = null;
boolean _startsWith = body.startsWith("\n");
if (_startsWith) {
_xifexpression = body.substring(1);
} else {
_xifexpression = body;
}
String result = _xifexpression;
String _xifexpression_1 = null;
boolean _startsWith_1 = result.startsWith("{\n");
if (_startsWith_1) {
String _xblockexpression_1 = null;
{
String _replace = result.replace("\n\t", "\n");
result = _replace;
int _length = result.length();
int _minus = (_length - 2);
_xblockexpression_1 = result.substring(1, _minus);
}
_xifexpression_1 = _xblockexpression_1;
} else {
_xifexpression_1 = result;
}
_xblockexpression = _xifexpression_1;
}
return _xblockexpression;
}
public Diagnostic generateGenModel(final GenModel genModel, final IFileSystemAccess fsa) {
Diagnostic _xifexpression = null;
String _modelDirectory = genModel.getModelDirectory();
boolean _notEquals = (!Objects.equal(_modelDirectory, null));
if (_notEquals) {
Diagnostic _xblockexpression = null;
{
genModel.setCanGenerate(true);
final XcoreGeneratorImpl generator = this.xcoreGeneratorImplProvider.get();
generator.setInput(genModel);
generator.setFileSystemAccess(fsa);
String _modelDirectory_1 = genModel.getModelDirectory();
generator.setModelDirectory(_modelDirectory_1);
BasicMonitor _basicMonitor = new BasicMonitor();
generator.generate(genModel, GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE, _basicMonitor);
BasicMonitor _basicMonitor_1 = new BasicMonitor();
generator.generate(genModel, GenBaseGeneratorAdapter.EDIT_PROJECT_TYPE, _basicMonitor_1);
BasicMonitor _basicMonitor_2 = new BasicMonitor();
generator.generate(genModel, GenBaseGeneratorAdapter.EDITOR_PROJECT_TYPE, _basicMonitor_2);
BasicMonitor _basicMonitor_3 = new BasicMonitor();
_xblockexpression = generator.generate(genModel, GenBaseGeneratorAdapter.TESTS_PROJECT_TYPE, _basicMonitor_3);
}
_xifexpression = _xblockexpression;
}
return _xifexpression;
}
}