diff options
author | ahaase | 2008-03-01 16:11:09 +0000 |
---|---|---|
committer | ahaase | 2008-03-01 16:11:09 +0000 |
commit | bdf4ee9881c68a94bb1158fe1e38b11735198c3a (patch) | |
tree | 649c11182037de52e8df52f4d094b527fb8197ee | |
parent | 378b5b8a841e3cb4971d6b5d42a2f6f88d20394b (diff) | |
download | org.eclipse.xpand-bdf4ee9881c68a94bb1158fe1e38b11735198c3a.tar.gz org.eclipse.xpand-bdf4ee9881c68a94bb1158fe1e38b11735198c3a.tar.xz org.eclipse.xpand-bdf4ee9881c68a94bb1158fe1e38b11735198c3a.zip |
merged middleend and emftypes plugins into backend plugin
9 files changed, 541 insertions, 4 deletions
diff --git a/plugins/org.eclipse.xtend.backend.uml2types/META-INF/MANIFEST.MF b/plugins/org.eclipse.xtend.backend.uml2types/META-INF/MANIFEST.MF index 9a9ba348..474f9cfe 100644 --- a/plugins/org.eclipse.xtend.backend.uml2types/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.xtend.backend.uml2types/META-INF/MANIFEST.MF @@ -5,6 +5,5 @@ Bundle-SymbolicName: org.eclipse.xtend.backend.uml2types Bundle-Version: 0.7.0 Require-Bundle: org.eclipse.xtend.backend, org.eclipse.uml2.uml, - org.apache.commons.logging, - org.eclipse.xtend.backend.emftypes + org.apache.commons.logging Bundle-Localization: plugin diff --git a/plugins/org.eclipse.xtend.backend/META-INF/MANIFEST.MF b/plugins/org.eclipse.xtend.backend/META-INF/MANIFEST.MF index 4357b098..1b43489e 100644 --- a/plugins/org.eclipse.xtend.backend/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.xtend.backend/META-INF/MANIFEST.MF @@ -19,6 +19,8 @@ Export-Package: org.eclipose.xtend.middleend, org.eclipse.xtend.backend.syslib, org.eclipse.xtend.backend.types;uses:="org.eclipse.xtend.backend.common", org.eclipse.xtend.backend.types.builtin;uses:="org.eclipse.xtend.backend.common,org.eclipse.xtend.backend.types", + org.eclipse.xtend.backend.types.emf, + org.eclipse.xtend.backend.types.emf.internal;x-internal:=true, org.eclipse.xtend.backend.types.java.internal;x-internal:=true, org.eclipse.xtend.backend.util Require-Bundle: org.apache.commons.logging, diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/EmfTypesystem.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/EmfTypesystem.java new file mode 100644 index 00000000..34dd7929 --- /dev/null +++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/EmfTypesystem.java @@ -0,0 +1,158 @@ +/* +Copyright (c) 2008 Arno Haase. +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: + Arno Haase - initial API and implementation + */ +package org.eclipse.xtend.backend.types.emf; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EEnumLiteral; +import org.eclipse.emf.ecore.ENamedElement; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.ETypedElement; +import org.eclipse.emf.ecore.EcorePackage; +import org.eclipse.xtend.backend.common.BackendType; +import org.eclipse.xtend.backend.common.BackendTypesystem; +import org.eclipse.xtend.backend.common.SyntaxConstants; +import org.eclipse.xtend.backend.types.builtin.BooleanType; +import org.eclipse.xtend.backend.types.builtin.DoubleType; +import org.eclipse.xtend.backend.types.builtin.ListType; +import org.eclipse.xtend.backend.types.builtin.LongType; +import org.eclipse.xtend.backend.types.builtin.ObjectType; +import org.eclipse.xtend.backend.types.builtin.StringType; +import org.eclipse.xtend.backend.types.emf.internal.EClassType; +import org.eclipse.xtend.backend.types.emf.internal.EDataTypeType; +import org.eclipse.xtend.backend.types.emf.internal.EEnumType; +import org.eclipse.xtend.backend.types.emf.internal.EObjectType; + + +/** + * + * @author Arno Haase (http://www.haase-consulting.com) + */ +public final class EmfTypesystem implements BackendTypesystem { + private BackendTypesystem _rootTypesystem; + + private final Map<EClassifier, BackendType> _cache = new HashMap<EClassifier, BackendType>(); + + private static final Map<EClassifier, BackendType> _ecorePrimitives = new HashMap<EClassifier, BackendType> (); + + static { + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEString(), StringType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEChar(), StringType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getECharacterObject(), StringType.INSTANCE); + + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEBoolean(), BooleanType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEBooleanObject(), BooleanType.INSTANCE); + + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEInt(), LongType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEIntegerObject(), LongType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getELong(), LongType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getELongObject(), LongType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEShort(), LongType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEShortObject(), LongType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEByte(), LongType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEByteObject(), LongType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEBigInteger(), LongType.INSTANCE); + + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEFloat(), DoubleType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEFloatObject(), DoubleType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEDouble(), DoubleType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEDoubleObject(), DoubleType.INSTANCE); + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEBigDecimal(), DoubleType.INSTANCE); + + _ecorePrimitives.put (EcorePackage.eINSTANCE.getEJavaObject(), ObjectType.INSTANCE); + } + + /** + * This method serves as the single point of access to the internal cache of types; all other methods that + * look up a type should go through this method. + */ + public BackendType getTypeForEClassifier (EClassifier cls) { + final BackendType cached = _cache.get (cls); + if (cached != null) + return cached; + + if (cls instanceof EClass) { + final EClassType result = new EClassType ((EClass) cls, this); + + // first putting the type into the cache and then initializing it avoids endless recursion + _cache.put (cls, result); + result.init (this); + return result; + } + + final BackendType result = getTypeForEClassifierRaw (cls); + _cache.put (cls, result); + return result; + } + + private BackendType getTypeForEClassifierRaw (EClassifier cls) { + if (cls instanceof EEnum) + return new EEnumType ((EEnum) cls); + + final BackendType primitiveCandidate = _ecorePrimitives.get (cls); + if (primitiveCandidate != null) + return primitiveCandidate; + + if (cls instanceof EDataType) + return new EDataTypeType ((EDataType) cls); + + return null; + } + + public BackendType findType(final Object obj) { + if (! (obj instanceof EObject)) + return null; + + if (obj instanceof EEnumLiteral) + return getTypeForEClassifier(((EEnumLiteral) obj).getEEnum()); + + return getTypeForEClassifier (((EObject) obj).eClass()); + } + + public BackendType getTypeForETypedElement (ETypedElement typedElement) { + if (typedElement.getUpperBound() != 1) + return ListType.INSTANCE; + + return getTypeForEClassifier(typedElement.getEType()); + } + + public static String getFullyQualifiedName (ENamedElement ele) { + return getFqnRec (ele.eContainer(), ele.getName()); + } + + private final static String getFqnRec (EObject ele, String suffix) { + if (ele == null || !(ele instanceof ENamedElement)) + return suffix; + else + return getFqnRec(ele.eContainer(), ((ENamedElement) ele).getName() + SyntaxConstants.NS_DELIM + suffix); + } + + public BackendType findType (Class<?> cls) { + if (EObject.class.isAssignableFrom(cls)) + return EObjectType.INSTANCE; + + return null; + } + + public BackendTypesystem getRootTypesystem () { + return _rootTypesystem; + } + + public void setRootTypesystem (BackendTypesystem ts) { + _rootTypesystem = ts; + } +} + diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/internal/EClassType.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/internal/EClassType.java new file mode 100644 index 00000000..605134c8 --- /dev/null +++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/internal/EClassType.java @@ -0,0 +1,173 @@ +/* +Copyright (c) 2008 Arno Haase. +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: + Arno Haase - initial API and implementation + */ +package org.eclipse.xtend.backend.types.emf.internal; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EOperation; +import org.eclipse.emf.ecore.EParameter; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.xtend.backend.common.BackendType; +import org.eclipse.xtend.backend.common.ExecutionContext; +import org.eclipse.xtend.backend.common.ExpressionBase; +import org.eclipse.xtend.backend.common.Function; +import org.eclipse.xtend.backend.types.AbstractProperty; +import org.eclipse.xtend.backend.types.AbstractType; +import org.eclipse.xtend.backend.types.emf.EmfTypesystem; +import org.eclipse.xtend.backend.util.CollectionHelper; +import org.eclipse.xtend.backend.util.ErrorHandler; + + +/** + * + * @author Arno Haase (http://www.haase-consulting.com) + */ +public final class EClassType extends AbstractType { + private final EClass _cls; + + public EClassType (EClass cls, EmfTypesystem ts) { + super (EmfTypesystem.getFullyQualifiedName(cls), superTypes(cls, ts)); + _cls = cls; + } + + /** + * This method is separated from the constructor to avoid endless recursion if a type has properties and/or + * operations that reference itself + */ + public void init (EmfTypesystem ts) { + initProperties (ts); + initOperations (ts); + } + + private void initProperties (EmfTypesystem ts) { + for (final EStructuralFeature feature: _cls.getEStructuralFeatures()) { + final BackendType t = ts.getTypeForETypedElement(feature); + + if (feature.isChangeable() && !feature.isUnsettable() && !feature.isDerived()) { + register (new AbstractProperty (this, t, feature.getEType().getInstanceClass(), feature.getName(), true) { + @Override + public Object getRaw (ExecutionContext ctx, Object o) { + return ((EObject) o).eGet(feature); + } + + @Override + public void setRaw (ExecutionContext ctx, Object o, Object newValue) { + ((EObject) o).eSet(feature, newValue); + } + }); + } + else { + register (new AbstractProperty (this, t, feature.getEType().getInstanceClass(), feature.getName(), false) { + @Override + public Object getRaw (ExecutionContext ctx, Object o) { + return ((EObject) o).eGet(feature); + } + }); + } + } + } + + private void initOperations (EmfTypesystem ts) { + for (final EOperation op: _cls.getEOperations()) { + final Class<?>[] paramClasses = new Class<?>[op.getEParameters().size()]; + + int i=0; + final List<BackendType> paramTypes = new ArrayList<BackendType>(); + paramTypes.add (ts.getTypeForETypedElement (op)); + + for (EParameter param: op.getEParameters()) { + paramTypes.add (ts.getTypeForETypedElement(param)); + paramClasses[i++] = param.getEType().getInstanceClass(); + } + + try { + final Method mtd = _cls.getInstanceClass().getMethod(op.getName(), paramClasses); + + register (op.getName(), new Function () { + public ExpressionBase getGuard () { + return null; + } + + public List<? extends BackendType> getParameterTypes () { + return paramTypes; + } + + public Object invoke (ExecutionContext ctx, Object[] params) { +// params[i] = getParameterTypes().get(i).convert(params[i], paramClasses[i]); + try { + return mtd.invoke(params[0], CollectionHelper.withoutFirst (params)); + } catch (Exception e) { + ErrorHandler.handle(e); + return null; // to make the compiler happy - this is never executed + } + } + + public boolean isCached () { + return false; + } + + }); + } catch (Exception e) { + ErrorHandler.handle (e); + } + } + } + + + @Override + public Object create () { + return _cls.getEPackage ().getEFactoryInstance ().create (_cls); + } + + private static Collection<? extends BackendType> superTypes (EClass eClass, EmfTypesystem ts) { + final Set<BackendType> result = new HashSet<BackendType>(); + + for (EClass ec: eClass.getESuperTypes()) + result.add (ts.getTypeForEClassifier(ec)); + + result.add (EObjectType.INSTANCE); + return result; + } + + @Override + public int hashCode () { + final int prime = 31; + int result = 1; + result = prime * result + ((_cls == null) ? 0 : _cls.hashCode()); + return result; + } + + @Override + public boolean equals (Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final EClassType other = (EClassType) obj; + if (_cls == null) { + if (other._cls != null) + return false; + } else if (!_cls.equals(other._cls)) + return false; + return true; + } +} + + diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/internal/EDataTypeType.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/internal/EDataTypeType.java new file mode 100644 index 00000000..e6f906b1 --- /dev/null +++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/internal/EDataTypeType.java @@ -0,0 +1,54 @@ +/* +Copyright (c) 2008 Arno Haase. +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: + Arno Haase - initial API and implementation + */ +package org.eclipse.xtend.backend.types.emf.internal; + +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.xtend.backend.types.AbstractType; +import org.eclipse.xtend.backend.types.emf.EmfTypesystem; + + +/** + * + * @author Arno Haase (http://www.haase-consulting.com) + */ +public final class EDataTypeType extends AbstractType { + private final EDataType _dt; + + public EDataTypeType (EDataType dt) { + super (EmfTypesystem.getFullyQualifiedName(dt)); + _dt = dt; + } + + @Override + public int hashCode () { + final int prime = 31; + int result = 1; + result = prime * result + ((_dt == null) ? 0 : _dt.hashCode()); + return result; + } + + @Override + public boolean equals (Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final EDataTypeType other = (EDataTypeType) obj; + if (_dt == null) { + if (other._dt != null) + return false; + } else if (!_dt.equals(other._dt)) + return false; + return true; + } +} diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/internal/EEnumType.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/internal/EEnumType.java new file mode 100644 index 00000000..63208bc7 --- /dev/null +++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/internal/EEnumType.java @@ -0,0 +1,78 @@ +/* +Copyright (c) 2008 Arno Haase. +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: + Arno Haase - initial API and implementation + */ +package org.eclipse.xtend.backend.types.emf.internal; + +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EEnumLiteral; +import org.eclipse.xtend.backend.common.BackendType; +import org.eclipse.xtend.backend.common.StaticProperty; +import org.eclipse.xtend.backend.types.AbstractType; +import org.eclipse.xtend.backend.types.emf.EmfTypesystem; + + +/** + * + * @author Arno Haase (http://www.haase-consulting.com) + */ +public final class EEnumType extends AbstractType { + private final EEnum _enum; + + public EEnumType (EEnum e) { + super (EmfTypesystem.getFullyQualifiedName(e), EObjectType.INSTANCE); + + _enum = e; + + for (final EEnumLiteral el: e.getELiterals()) + register (new StaticProperty () { + public Object get () { + return el.getInstance(); + } + + public String getName () { + return el.getName(); + } + + public BackendType getOwner () { + return EEnumType.this; + } + + public BackendType getType () { + return EEnumType.this; //TODO fix this + } + }); + } + + @Override + public int hashCode () { + final int prime = 31; + int result = 1; + result = prime * result + ((_enum == null) ? 0 : _enum.hashCode()); + return result; + } + + @Override + public boolean equals (Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final EEnumType other = (EEnumType) obj; + if (_enum == null) { + if (other._enum != null) + return false; + } else if (!_enum.equals(other._enum)) + return false; + return true; + } +} + diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/internal/EObjectType.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/internal/EObjectType.java new file mode 100644 index 00000000..29ffb964 --- /dev/null +++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/emf/internal/EObjectType.java @@ -0,0 +1,74 @@ +/* +Copyright (c) 2008 Arno Haase. +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: + Arno Haase - initial API and implementation + */ +package org.eclipse.xtend.backend.types.emf.internal; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.xtend.backend.common.BackendType; +import org.eclipse.xtend.backend.common.ExecutionContext; +import org.eclipse.xtend.backend.types.AbstractProperty; +import org.eclipse.xtend.backend.types.AbstractType; +import org.eclipse.xtend.backend.types.builtin.ListType; +import org.eclipse.xtend.backend.types.builtin.SetType; +import org.eclipse.xtend.backend.types.builtin.VoidType; + + +/** + * + * @author Arno Haase (http://www.haase-consulting.com) + */ +public final class EObjectType extends AbstractType { + public static final EObjectType INSTANCE = new EObjectType (); + + private EObjectType () { + super ("emf::EObject"); + + register (new AbstractProperty (INSTANCE, INSTANCE, EObject.class, "eContainer", false) { + @Override + public Object getRaw (ExecutionContext ctx, Object o) { + return ((EObject) o).eContainer(); + } + }); + register (new AbstractProperty (INSTANCE, ListType.INSTANCE, java.util.List.class, "eContents", false) { + @Override + public Object getRaw (ExecutionContext ctx, Object o) { + return ((EObject) o).eContents(); + } + }); + register (new AbstractProperty (INSTANCE, INSTANCE, EObject.class, "eRootContainer", false) { + @Override + public Object getRaw (ExecutionContext ctx, Object o) { + return EcoreUtil.getRootContainer((EObject) o); + } + }); + register (new AbstractProperty (INSTANCE, SetType.INSTANCE, java.util.Set.class, "eAllContents", false) { + @Override + public Object getRaw (ExecutionContext ctx, Object o) { + final Set<Object> result = new HashSet<Object>(); + + for (Iterator<?> iter = ((EObject) o).eAllContents(); iter.hasNext(); ) + result.add (iter.next()); + + return result; + } + }); + } + + @Override + public boolean isAssignableFrom (BackendType other) { + return other == this || other == VoidType.INSTANCE; + } +} + diff --git a/plugins/org.eclipse.xtend.backend/todo.txt b/plugins/org.eclipse.xtend.backend/todo.txt index 929c5035..16f4a200 100644 --- a/plugins/org.eclipse.xtend.backend/todo.txt +++ b/plugins/org.eclipse.xtend.backend/todo.txt @@ -1,6 +1,5 @@ todo ---- -merge middleend and backend merge emftypes into backend? "compiled" LangueSpecificMiddleEnd @@ -43,6 +42,7 @@ Debugger: ein Source-Primitive kann aus mehreren Runtime-Primitives bestehen - i tail recursion replace/add von Extensions im dynamischen Scope + Unterstützung ------------- UML und EMF testen diff --git a/plugins/org.eclipse.xtend.middleend.old/META-INF/MANIFEST.MF b/plugins/org.eclipse.xtend.middleend.old/META-INF/MANIFEST.MF index 27913d07..39a98b6f 100644 --- a/plugins/org.eclipse.xtend.middleend.old/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.xtend.middleend.old/META-INF/MANIFEST.MF @@ -5,7 +5,6 @@ Bundle-SymbolicName: org.eclipse.xtend.middleend.old;singleton:=true Bundle-Version: 0.7.0 Require-Bundle: org.eclipse.xtend.backend, org.eclipse.emf.ecore, - org.eclipse.xtend.backend.emftypes, org.eclipse.xtend, org.eclipse.xpand, org.eclipse.xtend.typesystem.emf, |