Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 29d79d72f17b777e9826ac070c5eaf2e4d03c994 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
/**
 * 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 v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 */
package org.eclipse.emf.ecore.xcore.generator;

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.GenModel;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage;
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.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.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);
        final EDataType eDataType = this.mappings.getMapping(xDataType).getEDataType();
        final XBlockExpression createBody = xDataType.getCreateBody();
        final JvmOperation creator = this.mappings.getMapping(xDataType).getCreator();
        if (((createBody != null) && (creator != null))) {
          final XcoreAppendable appendable = this.createAppendable();
          appendable.declareVariable(creator.getParameters().get(0), "it");
          this.compile(eDataType, "create", appendable, errors, createBody, creator.getReturnType(), Collections.<JvmTypeReference>emptySet());
        }
        final XBlockExpression convertBody = xDataType.getConvertBody();
        final JvmOperation converter = this.mappings.getMapping(xDataType).getConverter();
        if (((convertBody != null) && (converter != null))) {
          final XcoreAppendable appendable_1 = this.createAppendable();
          appendable_1.declareVariable(converter.getParameters().get(0), "it");
          this.compile(eDataType, "convert", appendable_1, errors, convertBody, converter.getReturnType(), Collections.<JvmTypeReference>emptySet());
        }
      } else {
        final XClass xClass = ((XClass) xClassifier);
        final EClass eClass = this.mappings.getMapping(xClass).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);
            if ((xFeature != null)) {
              final XBlockExpression getBody = xFeature.getGetBody();
              if ((getBody != null)) {
                final JvmOperation getter = this.mappings.getMapping(xFeature).getGetter();
                final XcoreAppendable appendable_2 = this.createAppendable();
                appendable_2.declareVariable(getter.getDeclaringType(), "this");
                final JvmTypeReference superType = IterableExtensions.<JvmTypeReference>head(getter.getDeclaringType().getSuperTypes());
                if ((superType != null)) {
                  appendable_2.declareVariable(superType.getType(), "super");
                }
                this.compile(eStructuralFeature, "get", appendable_2, errors, getBody, getter.getReturnType(), Collections.<JvmTypeReference>emptySet());
              }
            }
          }
        }
        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);
            if ((xOperation != null)) {
              final XBlockExpression body = xOperation.getBody();
              if ((body != null)) {
                final XOperationMapping xOperationMapping = this.mappings.getMapping(xOperation);
                final JvmOperation jvmOperation = xOperationMapping.getJvmOperation();
                if ((jvmOperation != null)) {
                  final XcoreAppendable appendable_3 = this.createAppendable();
                  JvmDeclaredType declaringType = jvmOperation.getDeclaringType();
                  boolean _isExternalInterface = xOperationMapping.getGenOperation().getGenClass().isExternalInterface();
                  if (_isExternalInterface) {
                    final EList<JvmTypeReference> superTypes = declaringType.getSuperTypes();
                    final JvmTypeReference effectiveTypeReference = IterableExtensions.<JvmTypeReference>head(superTypes);
                    if ((effectiveTypeReference != null)) {
                      appendable_3.declareVariable(effectiveTypeReference.getType(), "this");
                    }
                  } else {
                    appendable_3.declareVariable(declaringType, "this");
                    final JvmTypeReference superType_1 = IterableExtensions.<JvmTypeReference>head(declaringType.getSuperTypes());
                    if ((superType_1 != null)) {
                      appendable_3.declareVariable(superType_1.getType(), "super");
                    }
                  }
                  EList<JvmFormalParameter> _parameters = jvmOperation.getParameters();
                  for (final JvmFormalParameter parameter : _parameters) {
                    appendable_3.declareVariable(parameter, parameter.getName());
                  }
                  JvmTypeReference _returnType = jvmOperation.getReturnType();
                  EList<JvmTypeReference> _exceptions = jvmOperation.getExceptions();
                  HashSet<JvmTypeReference> _hashSet = new HashSet<JvmTypeReference>(_exceptions);
                  this.compile(eOperation, "body", appendable_3, errors, body, _returnType, _hashSet);
                }
              }
            }
          }
        }
      }
    }
  }
  
  @Override
  public void doGenerate(final Resource resource, final IFileSystemAccess fsa) {
    EObject _head = IterableExtensions.<EObject>head(resource.getContents());
    this.generateBodyAnnotations(((XPackage) _head));
    this.generateGenModel(IterableExtensions.<GenModel>head(Iterables.<GenModel>filter(resource.getContents(), GenModel.class)), 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) {
        boolean _isAncestor = EcoreUtil.isAncestor(body, error.getKey());
        if (_isAncestor) {
          String _value = error.getValue();
          throw new RuntimeException(_value);
        }
      }
      this.compiler.compile(body, appendable, returnType, exceptions);
      EcoreUtil.setAnnotation(target, GenModelPackage.eNS_URI, key, this.extractBody(appendable.toString()));
    } catch (final Throwable _t) {
      if (_t instanceof Throwable) {
        final Throwable throwable = (Throwable)_t;
        String _xifexpression = null;
        String _message = throwable.getMessage();
        boolean _tripleEquals = (_message == null);
        if (_tripleEquals) {
          _xifexpression = "throw new <%java.lang.Error%>(\"Unresolved compilation problem\");";
        } else {
          String _unicodeEscapeEncode = CodeGenUtil.unicodeEscapeEncode(throwable.getMessage());
          String _plus = ("throw new <%java.lang.Error%>(\"Unresolved compilation problems: " + _unicodeEscapeEncode);
          _xifexpression = (_plus + "\");");
        }
        final String message = _xifexpression;
        EcoreUtil.setAnnotation(target, GenModelPackage.eNS_URI, key, message);
      } 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();
        if ((uri != null)) {
          final EObject eObject = resource.getEObject(uri.fragment());
          if ((eObject != null)) {
            result.put(eObject, ((XtextLinkingDiagnostic)diagnostic).getMessage());
          }
        }
      }
    }
    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;
        {
          result = result.replace("\n\t", "\n");
          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 _tripleNotEquals = (_modelDirectory != null);
    if (_tripleNotEquals) {
      Diagnostic _xblockexpression = null;
      {
        genModel.setCanGenerate(true);
        final XcoreGeneratorImpl generator = this.xcoreGeneratorImplProvider.get();
        generator.setInput(genModel);
        generator.setFileSystemAccess(fsa);
        generator.setModelDirectory(genModel.getModelDirectory());
        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;
  }
}

Back to the top