diff --git a/org.eclipse.xtext.common.types.tests/tests/org/eclipse/xtext/common/types/JvmGenericClassTest.java b/org.eclipse.xtext.common.types.tests/tests/org/eclipse/xtext/common/types/JvmGenericClassTest.java new file mode 100644 index 00000000000..dc815284051 --- /dev/null +++ b/org.eclipse.xtext.common.types.tests/tests/org/eclipse/xtext/common/types/JvmGenericClassTest.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2023 itemis AG (http://www.itemis.eu) and others. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.xtext.common.types; + +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +/** + * @author LorenzoBettini - Initial contribution and API + */ +public class JvmGenericClassTest extends JvmGenericTypeTest { + + private JvmGenericClass genericClass; + + @Override + @Before + public void setUp() throws Exception { + genericClass = TypesFactory.eINSTANCE.createJvmGenericClass(); + genericType = genericClass; + } + + @Test public void testSetClassToExtendsUpdatesSuperTypes() { + JvmTypeReference classToExtend = createTypeReference(); + genericClass.setClassToExtend(classToExtend); + assertNotNull(genericClass.getClassToExtend()); + assertSame(classToExtend, genericClass.getSuperTypes().get(0)); + // if we unset the class to extend... + genericClass.setClassToExtend(null); + assertNull(genericClass.getClassToExtend()); + // ... it must also be removed from supertypes + assertEquals(0, genericClass.getSuperTypes().size()); + } + + @Test public void testUpdateSuperTypesSetsClassToExtend() { + JvmTypeReference classToExtend = createTypeReference(); + JvmTypeReference anotherType = createTypeReference(); + genericClass.setClassToExtend(classToExtend); + assertNotNull(genericClass.getClassToExtend()); + assertSame(classToExtend, genericClass.getSuperTypes().get(0)); + + genericClass.getSuperTypes().add(anotherType); + assertEquals(2, genericClass.getSuperTypes().size()); + // if we remove a super type that is not the class to extend... + genericClass.getSuperTypes().remove(anotherType); + assertEquals(1, genericClass.getSuperTypes().size()); + // ... the extended class is still there + assertNotNull(genericClass.getClassToExtend()); + // ... otherwise ... + genericClass.getSuperTypes().clear(); + // ... the class to extend is unset as well ... + assertNull(genericClass.getClassToExtend()); + } + + @Test public void testUpdateInterfacesToImplementUpdatesSuperTypes() { + JvmTypeReference interface1 = createTypeReference(); + JvmTypeReference interface2 = createTypeReference(); + genericClass.getInterfacesToImplement().addAll(List.of(interface1, interface2)); + assertEquals(2, genericClass.getInterfacesToImplement().size()); + var superTypes = genericClass.getSuperTypes(); + assertEquals(genericClass.getInterfacesToImplement(), superTypes); + // call it twice to make sure it doesn't change + var superTypes2 = genericClass.getSuperTypes(); + assertEquals(genericClass.getInterfacesToImplement(), superTypes2); + // remove from interface to implement ... + genericClass.getInterfacesToImplement().remove(0); + assertEquals(1, genericClass.getInterfacesToImplement().size()); + // ... and the interface must be removed from supertypes as well + assertEquals(genericClass.getInterfacesToImplement(), genericClass.getSuperTypes()); + } + + @Test public void testUpdateSuperTypesUpdatesInterfacesToImplement() { + JvmTypeReference interface1 = createTypeReference(); + JvmTypeReference interface2 = createTypeReference(); + JvmTypeReference anotherType = createTypeReference(); + genericClass.getInterfacesToImplement().addAll(List.of(interface1, interface2)); + assertEquals(2, genericClass.getInterfacesToImplement().size()); + var superTypes = genericClass.getSuperTypes(); + assertEquals(genericClass.getInterfacesToImplement(), superTypes); + + genericClass.getSuperTypes().add(anotherType); + assertEquals(3, genericClass.getSuperTypes().size()); + // if we remove a super type that is not an interface to implement... + genericClass.getSuperTypes().remove(anotherType); + assertEquals(2, genericClass.getSuperTypes().size()); + // ... the interface to implement is still there + assertEquals(2, genericClass.getInterfacesToImplement().size()); + // ... otherwise ... + genericClass.getSuperTypes().clear(); + // ... the interface to implement is removed as well ... + assertEquals(0, genericClass.getInterfacesToImplement().size()); + } + + private JvmTypeReference createTypeReference() { + return createReferenceTo( + TypesFactory.eINSTANCE.createJvmGenericType()); + } +} diff --git a/org.eclipse.xtext.common.types.tests/tests/org/eclipse/xtext/common/types/JvmGenericTypeTest.java b/org.eclipse.xtext.common.types.tests/tests/org/eclipse/xtext/common/types/JvmGenericTypeTest.java index 41d45df777a..fa96b44069c 100644 --- a/org.eclipse.xtext.common.types.tests/tests/org/eclipse/xtext/common/types/JvmGenericTypeTest.java +++ b/org.eclipse.xtext.common.types.tests/tests/org/eclipse/xtext/common/types/JvmGenericTypeTest.java @@ -20,7 +20,7 @@ */ public class JvmGenericTypeTest extends JvmDeclaredTypeTest { - private JvmGenericType genericType; + protected JvmGenericType genericType; @Before public void setUp() throws Exception { @@ -52,7 +52,7 @@ protected JvmGenericType getObjectUnderTest() { assertTrue(Iterables.isEmpty(interfaces)); } - private JvmTypeReference createReferenceTo(JvmType type) { + protected JvmTypeReference createReferenceTo(JvmType type) { JvmParameterizedTypeReference result = TypesFactory.eINSTANCE.createJvmParameterizedTypeReference(); result.setType(type); return result; diff --git a/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/JvmGenericClass.java b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/JvmGenericClass.java new file mode 100644 index 00000000000..62f5e454504 --- /dev/null +++ b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/JvmGenericClass.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2011-2020 itemis AG (http://www.itemis.eu) and others. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.xtext.common.types; + +import org.eclipse.emf.common.util.EList; + +/** + * + * A representation of the model object 'Jvm Generic Class'. + * + * + *

+ * The following features are supported: + *

+ * + * + * @see org.eclipse.xtext.common.types.TypesPackage#getJvmGenericClass() + * @model + * @generated + */ +public interface JvmGenericClass extends JvmGenericType +{ + /** + * Returns the value of the 'Class To Extend' reference. + * + * + * @return the value of the 'Class To Extend' reference. + * @see #setClassToExtend(JvmTypeReference) + * @see org.eclipse.xtext.common.types.TypesPackage#getJvmGenericClass_ClassToExtend() + * @model + * @generated + */ + JvmTypeReference getClassToExtend(); + + /** + * Sets the value of the '{@link org.eclipse.xtext.common.types.JvmGenericClass#getClassToExtend Class To Extend}' reference. + * + * + * @param value the new value of the 'Class To Extend' reference. + * @see #getClassToExtend() + * @generated + */ + void setClassToExtend(JvmTypeReference value); + + /** + * Returns the value of the 'Interfaces To Implement' reference list. + * The list contents are of type {@link org.eclipse.xtext.common.types.JvmTypeReference}. + * + * + * @return the value of the 'Interfaces To Implement' reference list. + * @see org.eclipse.xtext.common.types.TypesPackage#getJvmGenericClass_InterfacesToImplement() + * @model resolveProxies="false" + * @generated + */ + EList getInterfacesToImplement(); + +} // JvmGenericClass diff --git a/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/TypesFactory.java b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/TypesFactory.java index 536463f1aea..5c3be23cb01 100644 --- a/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/TypesFactory.java +++ b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/TypesFactory.java @@ -361,6 +361,15 @@ public interface TypesFactory extends EFactory */ JvmInnerTypeReference createJvmInnerTypeReference(); + /** + * Returns a new object of class 'Jvm Generic Class'. + * + * + * @return a new object of class 'Jvm Generic Class'. + * @generated + */ + JvmGenericClass createJvmGenericClass(); + /** * Returns the package supported by this factory. * diff --git a/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/TypesPackage.java b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/TypesPackage.java index 3097a5bddf9..dff888995db 100644 --- a/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/TypesPackage.java +++ b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/TypesPackage.java @@ -2916,6 +2916,196 @@ public interface TypesPackage extends EPackage */ int JVM_INNER_TYPE_REFERENCE_FEATURE_COUNT = JVM_PARAMETERIZED_TYPE_REFERENCE_FEATURE_COUNT + 1; + /** + * The meta object id for the '{@link org.eclipse.xtext.common.types.impl.JvmGenericClassImpl Jvm Generic Class}' class. + * + * + * @see org.eclipse.xtext.common.types.impl.JvmGenericClassImpl + * @see org.eclipse.xtext.common.types.impl.TypesPackageImpl#getJvmGenericClass() + * @generated + */ + int JVM_GENERIC_CLASS = 52; + + /** + * The feature id for the 'Annotations' containment reference list. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__ANNOTATIONS = JVM_GENERIC_TYPE__ANNOTATIONS; + + /** + * The feature id for the 'Declaring Type' container reference. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__DECLARING_TYPE = JVM_GENERIC_TYPE__DECLARING_TYPE; + + /** + * The feature id for the 'Visibility' attribute. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__VISIBILITY = JVM_GENERIC_TYPE__VISIBILITY; + + /** + * The feature id for the 'Simple Name' attribute. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__SIMPLE_NAME = JVM_GENERIC_TYPE__SIMPLE_NAME; + + /** + * The feature id for the 'Identifier' attribute. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__IDENTIFIER = JVM_GENERIC_TYPE__IDENTIFIER; + + /** + * The feature id for the 'Deprecated' attribute. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__DEPRECATED = JVM_GENERIC_TYPE__DEPRECATED; + + /** + * The feature id for the 'Array Type' containment reference. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__ARRAY_TYPE = JVM_GENERIC_TYPE__ARRAY_TYPE; + + /** + * The feature id for the 'Super Types' containment reference list. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__SUPER_TYPES = JVM_GENERIC_TYPE__SUPER_TYPES; + + /** + * The feature id for the 'Members' containment reference list. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__MEMBERS = JVM_GENERIC_TYPE__MEMBERS; + + /** + * The feature id for the 'Abstract' attribute. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__ABSTRACT = JVM_GENERIC_TYPE__ABSTRACT; + + /** + * The feature id for the 'Static' attribute. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__STATIC = JVM_GENERIC_TYPE__STATIC; + + /** + * The feature id for the 'Final' attribute. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__FINAL = JVM_GENERIC_TYPE__FINAL; + + /** + * The feature id for the 'Package Name' attribute. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__PACKAGE_NAME = JVM_GENERIC_TYPE__PACKAGE_NAME; + + /** + * The feature id for the 'Type Parameters' containment reference list. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__TYPE_PARAMETERS = JVM_GENERIC_TYPE__TYPE_PARAMETERS; + + /** + * The feature id for the 'Interface' attribute. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__INTERFACE = JVM_GENERIC_TYPE__INTERFACE; + + /** + * The feature id for the 'Strict Floating Point' attribute. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__STRICT_FLOATING_POINT = JVM_GENERIC_TYPE__STRICT_FLOATING_POINT; + + /** + * The feature id for the 'Anonymous' attribute. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__ANONYMOUS = JVM_GENERIC_TYPE__ANONYMOUS; + + /** + * The feature id for the 'Class To Extend' reference. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__CLASS_TO_EXTEND = JVM_GENERIC_TYPE_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Interfaces To Implement' reference list. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS__INTERFACES_TO_IMPLEMENT = JVM_GENERIC_TYPE_FEATURE_COUNT + 1; + + /** + * The number of structural features of the 'Jvm Generic Class' class. + * + * + * @generated + * @ordered + */ + int JVM_GENERIC_CLASS_FEATURE_COUNT = JVM_GENERIC_TYPE_FEATURE_COUNT + 2; + /** * The meta object id for the '{@link org.eclipse.xtext.common.types.JvmVisibility Jvm Visibility}' enum. * @@ -2924,7 +3114,7 @@ public interface TypesPackage extends EPackage * @see org.eclipse.xtext.common.types.impl.TypesPackageImpl#getJvmVisibility() * @generated */ - int JVM_VISIBILITY = 52; + int JVM_VISIBILITY = 53; /** * The meta object id for the 'Iterable' data type. @@ -2934,7 +3124,7 @@ public interface TypesPackage extends EPackage * @see org.eclipse.xtext.common.types.impl.TypesPackageImpl#getIterable() * @generated */ - int ITERABLE = 53; + int ITERABLE = 54; /** * The meta object id for the 'IType Reference Visitor' data type. @@ -2944,7 +3134,7 @@ public interface TypesPackage extends EPackage * @see org.eclipse.xtext.common.types.impl.TypesPackageImpl#getITypeReferenceVisitor() * @generated */ - int ITYPE_REFERENCE_VISITOR = 54; + int ITYPE_REFERENCE_VISITOR = 55; /** * The meta object id for the 'IType Reference Visitor With Parameter' data type. @@ -2954,7 +3144,7 @@ public interface TypesPackage extends EPackage * @see org.eclipse.xtext.common.types.impl.TypesPackageImpl#getITypeReferenceVisitorWithParameter() * @generated */ - int ITYPE_REFERENCE_VISITOR_WITH_PARAMETER = 55; + int ITYPE_REFERENCE_VISITOR_WITH_PARAMETER = 56; /** @@ -4281,6 +4471,38 @@ public interface TypesPackage extends EPackage */ EReference getJvmInnerTypeReference_Outer(); + /** + * Returns the meta object for class '{@link org.eclipse.xtext.common.types.JvmGenericClass Jvm Generic Class}'. + * + * + * @return the meta object for class 'Jvm Generic Class'. + * @see org.eclipse.xtext.common.types.JvmGenericClass + * @generated + */ + EClass getJvmGenericClass(); + + /** + * Returns the meta object for the reference '{@link org.eclipse.xtext.common.types.JvmGenericClass#getClassToExtend Class To Extend}'. + * + * + * @return the meta object for the reference 'Class To Extend'. + * @see org.eclipse.xtext.common.types.JvmGenericClass#getClassToExtend() + * @see #getJvmGenericClass() + * @generated + */ + EReference getJvmGenericClass_ClassToExtend(); + + /** + * Returns the meta object for the reference list '{@link org.eclipse.xtext.common.types.JvmGenericClass#getInterfacesToImplement Interfaces To Implement}'. + * + * + * @return the meta object for the reference list 'Interfaces To Implement'. + * @see org.eclipse.xtext.common.types.JvmGenericClass#getInterfacesToImplement() + * @see #getJvmGenericClass() + * @generated + */ + EReference getJvmGenericClass_InterfacesToImplement(); + /** * Returns the meta object for enum '{@link org.eclipse.xtext.common.types.JvmVisibility Jvm Visibility}'. * @@ -5452,6 +5674,32 @@ interface Literals */ EReference JVM_INNER_TYPE_REFERENCE__OUTER = eINSTANCE.getJvmInnerTypeReference_Outer(); + /** + * The meta object literal for the '{@link org.eclipse.xtext.common.types.impl.JvmGenericClassImpl Jvm Generic Class}' class. + * + * + * @see org.eclipse.xtext.common.types.impl.JvmGenericClassImpl + * @see org.eclipse.xtext.common.types.impl.TypesPackageImpl#getJvmGenericClass() + * @generated + */ + EClass JVM_GENERIC_CLASS = eINSTANCE.getJvmGenericClass(); + + /** + * The meta object literal for the 'Class To Extend' reference feature. + * + * + * @generated + */ + EReference JVM_GENERIC_CLASS__CLASS_TO_EXTEND = eINSTANCE.getJvmGenericClass_ClassToExtend(); + + /** + * The meta object literal for the 'Interfaces To Implement' reference list feature. + * + * + * @generated + */ + EReference JVM_GENERIC_CLASS__INTERFACES_TO_IMPLEMENT = eINSTANCE.getJvmGenericClass_InterfacesToImplement(); + /** * The meta object literal for the '{@link org.eclipse.xtext.common.types.JvmVisibility Jvm Visibility}' enum. * diff --git a/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/impl/JvmGenericClassImpl.java b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/impl/JvmGenericClassImpl.java new file mode 100644 index 00000000000..17f8e2a84b4 --- /dev/null +++ b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/impl/JvmGenericClassImpl.java @@ -0,0 +1,224 @@ +/** + * Copyright (c) 2011-2020 itemis AG (http://www.itemis.eu) and others. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.xtext.common.types.impl; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +import org.eclipse.emf.ecore.util.EObjectEList; + +import org.eclipse.xtext.common.types.JvmGenericClass; +import org.eclipse.xtext.common.types.JvmTypeReference; +import org.eclipse.xtext.common.types.TypesPackage; + +/** + * + * An implementation of the model object 'Jvm Generic Class'. + * + *

+ * The following features are implemented: + *

+ * + * + * @generated + */ +public class JvmGenericClassImpl extends JvmGenericTypeImplCustom implements JvmGenericClass +{ + /** + * The cached value of the '{@link #getClassToExtend() Class To Extend}' reference. + * + * + * @see #getClassToExtend() + * @generated + * @ordered + */ + protected JvmTypeReference classToExtend; + + /** + * The cached value of the '{@link #getInterfacesToImplement() Interfaces To Implement}' reference list. + * + * + * @see #getInterfacesToImplement() + * @generated + * @ordered + */ + protected EList interfacesToImplement; + + /** + * + * + * @generated + */ + protected JvmGenericClassImpl() + { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() + { + return TypesPackage.Literals.JVM_GENERIC_CLASS; + } + + /** + * + * + * @generated + */ + @Override + public JvmTypeReference getClassToExtend() + { + if (classToExtend != null && classToExtend.eIsProxy()) + { + InternalEObject oldClassToExtend = (InternalEObject)classToExtend; + classToExtend = (JvmTypeReference)eResolveProxy(oldClassToExtend); + if (classToExtend != oldClassToExtend) + { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, TypesPackage.JVM_GENERIC_CLASS__CLASS_TO_EXTEND, oldClassToExtend, classToExtend)); + } + } + return classToExtend; + } + + /** + * + * + * @generated + */ + public JvmTypeReference basicGetClassToExtend() + { + return classToExtend; + } + + /** + * + * + * @generated + */ + @Override + public void setClassToExtend(JvmTypeReference newClassToExtend) + { + JvmTypeReference oldClassToExtend = classToExtend; + classToExtend = newClassToExtend; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, TypesPackage.JVM_GENERIC_CLASS__CLASS_TO_EXTEND, oldClassToExtend, classToExtend)); + } + + /** + * + * + * @generated + */ + @Override + public EList getInterfacesToImplement() + { + if (interfacesToImplement == null) + { + interfacesToImplement = new EObjectEList(JvmTypeReference.class, this, TypesPackage.JVM_GENERIC_CLASS__INTERFACES_TO_IMPLEMENT); + } + return interfacesToImplement; + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case TypesPackage.JVM_GENERIC_CLASS__CLASS_TO_EXTEND: + if (resolve) return getClassToExtend(); + return basicGetClassToExtend(); + case TypesPackage.JVM_GENERIC_CLASS__INTERFACES_TO_IMPLEMENT: + return getInterfacesToImplement(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @SuppressWarnings("unchecked") + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case TypesPackage.JVM_GENERIC_CLASS__CLASS_TO_EXTEND: + setClassToExtend((JvmTypeReference)newValue); + return; + case TypesPackage.JVM_GENERIC_CLASS__INTERFACES_TO_IMPLEMENT: + getInterfacesToImplement().clear(); + getInterfacesToImplement().addAll((Collection)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case TypesPackage.JVM_GENERIC_CLASS__CLASS_TO_EXTEND: + setClassToExtend((JvmTypeReference)null); + return; + case TypesPackage.JVM_GENERIC_CLASS__INTERFACES_TO_IMPLEMENT: + getInterfacesToImplement().clear(); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case TypesPackage.JVM_GENERIC_CLASS__CLASS_TO_EXTEND: + return classToExtend != null; + case TypesPackage.JVM_GENERIC_CLASS__INTERFACES_TO_IMPLEMENT: + return interfacesToImplement != null && !interfacesToImplement.isEmpty(); + } + return super.eIsSet(featureID); + } + +} //JvmGenericClassImpl diff --git a/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/impl/TypesFactoryImpl.java b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/impl/TypesFactoryImpl.java index 464e70d34a2..f7fbd03be62 100644 --- a/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/impl/TypesFactoryImpl.java +++ b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/impl/TypesFactoryImpl.java @@ -108,6 +108,7 @@ public EObject create(EClass eClass) case TypesPackage.JVM_UNKNOWN_TYPE_REFERENCE: return createJvmUnknownTypeReference(); case TypesPackage.JVM_CUSTOM_ANNOTATION_VALUE: return createJvmCustomAnnotationValue(); case TypesPackage.JVM_INNER_TYPE_REFERENCE: return createJvmInnerTypeReference(); + case TypesPackage.JVM_GENERIC_CLASS: return createJvmGenericClass(); default: throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); } @@ -595,6 +596,18 @@ public JvmInnerTypeReference createJvmInnerTypeReference() return jvmInnerTypeReference; } + /** + * + * + * @generated + */ + @Override + public JvmGenericClass createJvmGenericClass() + { + JvmGenericClassImplCustom jvmGenericClass = new JvmGenericClassImplCustom(); + return jvmGenericClass; + } + /** * * diff --git a/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/impl/TypesPackageImpl.java b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/impl/TypesPackageImpl.java index 3eb921db651..eea89ac75c3 100644 --- a/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/impl/TypesPackageImpl.java +++ b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/impl/TypesPackageImpl.java @@ -47,6 +47,7 @@ import org.eclipse.xtext.common.types.JvmFloatAnnotationValue; import org.eclipse.xtext.common.types.JvmFormalParameter; import org.eclipse.xtext.common.types.JvmGenericArrayTypeReference; +import org.eclipse.xtext.common.types.JvmGenericClass; import org.eclipse.xtext.common.types.JvmGenericType; import org.eclipse.xtext.common.types.JvmIdentifiableElement; import org.eclipse.xtext.common.types.JvmInnerTypeReference; @@ -451,6 +452,13 @@ public class TypesPackageImpl extends EPackageImpl implements TypesPackage */ private EClass jvmInnerTypeReferenceEClass = null; + /** + * + * + * @generated + */ + private EClass jvmGenericClassEClass = null; + /** * * @@ -1917,6 +1925,39 @@ public EReference getJvmInnerTypeReference_Outer() return (EReference)jvmInnerTypeReferenceEClass.getEStructuralFeatures().get(0); } + /** + * + * + * @generated + */ + @Override + public EClass getJvmGenericClass() + { + return jvmGenericClassEClass; + } + + /** + * + * + * @generated + */ + @Override + public EReference getJvmGenericClass_ClassToExtend() + { + return (EReference)jvmGenericClassEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + @Override + public EReference getJvmGenericClass_InterfacesToImplement() + { + return (EReference)jvmGenericClassEClass.getEStructuralFeatures().get(1); + } + /** * * @@ -2169,6 +2210,10 @@ public void createPackageContents() jvmInnerTypeReferenceEClass = createEClass(JVM_INNER_TYPE_REFERENCE); createEReference(jvmInnerTypeReferenceEClass, JVM_INNER_TYPE_REFERENCE__OUTER); + jvmGenericClassEClass = createEClass(JVM_GENERIC_CLASS); + createEReference(jvmGenericClassEClass, JVM_GENERIC_CLASS__CLASS_TO_EXTEND); + createEReference(jvmGenericClassEClass, JVM_GENERIC_CLASS__INTERFACES_TO_IMPLEMENT); + // Create enums jvmVisibilityEEnum = createEEnum(JVM_VISIBILITY); @@ -2261,6 +2306,7 @@ public void initializePackageContents() jvmCompoundTypeReferenceEClass.getESuperTypes().add(this.getJvmTypeReference()); jvmCustomAnnotationValueEClass.getESuperTypes().add(this.getJvmAnnotationValue()); jvmInnerTypeReferenceEClass.getESuperTypes().add(this.getJvmParameterizedTypeReference()); + jvmGenericClassEClass.getESuperTypes().add(this.getJvmGenericType()); // Initialize classes and features; add operations and parameters initEClass(jvmIdentifiableElementEClass, JvmIdentifiableElement.class, "JvmIdentifiableElement", IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); @@ -2583,6 +2629,10 @@ public void initializePackageContents() initEClass(jvmInnerTypeReferenceEClass, JvmInnerTypeReference.class, "JvmInnerTypeReference", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEReference(getJvmInnerTypeReference_Outer(), this.getJvmParameterizedTypeReference(), null, "outer", null, 0, 1, JvmInnerTypeReference.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEClass(jvmGenericClassEClass, JvmGenericClass.class, "JvmGenericClass", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getJvmGenericClass_ClassToExtend(), this.getJvmTypeReference(), null, "classToExtend", null, 0, 1, JvmGenericClass.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getJvmGenericClass_InterfacesToImplement(), this.getJvmTypeReference(), null, "interfacesToImplement", null, 0, -1, JvmGenericClass.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + // Initialize enums and add enum literals initEEnum(jvmVisibilityEEnum, JvmVisibility.class, "JvmVisibility"); addEEnumLiteral(jvmVisibilityEEnum, JvmVisibility.DEFAULT); diff --git a/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/util/TypesAdapterFactory.java b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/util/TypesAdapterFactory.java index 4cab6505b42..d4c1a7fb741 100644 --- a/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/util/TypesAdapterFactory.java +++ b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/util/TypesAdapterFactory.java @@ -341,6 +341,11 @@ public Adapter caseJvmInnerTypeReference(JvmInnerTypeReference object) return createJvmInnerTypeReferenceAdapter(); } @Override + public Adapter caseJvmGenericClass(JvmGenericClass object) + { + return createJvmGenericClassAdapter(); + } + @Override public Adapter defaultCase(EObject object) { return createEObjectAdapter(); @@ -1142,6 +1147,21 @@ public Adapter createJvmInnerTypeReferenceAdapter() return null; } + /** + * Creates a new adapter for an object of class '{@link org.eclipse.xtext.common.types.JvmGenericClass Jvm Generic Class}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.eclipse.xtext.common.types.JvmGenericClass + * @generated + */ + public Adapter createJvmGenericClassAdapter() + { + return null; + } + /** * Creates a new adapter for the default case. * diff --git a/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/util/TypesSwitch.java b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/util/TypesSwitch.java index d5a2bc6e413..be160f18bae 100644 --- a/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/util/TypesSwitch.java +++ b/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/util/TypesSwitch.java @@ -545,6 +545,21 @@ protected T doSwitch(int classifierID, EObject theEObject) if (result == null) result = defaultCase(theEObject); return result; } + case TypesPackage.JVM_GENERIC_CLASS: + { + JvmGenericClass jvmGenericClass = (JvmGenericClass)theEObject; + T result = caseJvmGenericClass(jvmGenericClass); + if (result == null) result = caseJvmGenericType(jvmGenericClass); + if (result == null) result = caseJvmDeclaredType(jvmGenericClass); + if (result == null) result = caseJvmTypeParameterDeclarator(jvmGenericClass); + if (result == null) result = caseJvmMember(jvmGenericClass); + if (result == null) result = caseJvmComponentType(jvmGenericClass); + if (result == null) result = caseJvmAnnotationTarget(jvmGenericClass); + if (result == null) result = caseJvmType(jvmGenericClass); + if (result == null) result = caseJvmIdentifiableElement(jvmGenericClass); + if (result == null) result = defaultCase(theEObject); + return result; + } default: return defaultCase(theEObject); } } @@ -1381,6 +1396,22 @@ public T caseJvmInnerTypeReference(JvmInnerTypeReference object) return null; } + /** + * Returns the result of interpreting the object as an instance of 'Jvm Generic Class'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Jvm Generic Class'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseJvmGenericClass(JvmGenericClass object) + { + return null; + } + /** * Returns the result of interpreting the object as an instance of 'EObject'. * diff --git a/org.eclipse.xtext.common.types/model/JavaVMTypes.ecore b/org.eclipse.xtext.common.types/model/JavaVMTypes.ecore index 35c92ad7e1d..7de2a443c0e 100644 --- a/org.eclipse.xtext.common.types/model/JavaVMTypes.ecore +++ b/org.eclipse.xtext.common.types/model/JavaVMTypes.ecore @@ -398,4 +398,9 @@ + + + + diff --git a/org.eclipse.xtext.common.types/model/JavaVMTypes.genmodel b/org.eclipse.xtext.common.types/model/JavaVMTypes.genmodel index 107415dd89b..b108f34c2fb 100644 --- a/org.eclipse.xtext.common.types/model/JavaVMTypes.genmodel +++ b/org.eclipse.xtext.common.types/model/JavaVMTypes.genmodel @@ -258,5 +258,9 @@ + + + + diff --git a/org.eclipse.xtext.common.types/src/org/eclipse/xtext/common/types/impl/JvmGenericClassImplCustom.java b/org.eclipse.xtext.common.types/src/org/eclipse/xtext/common/types/impl/JvmGenericClassImplCustom.java new file mode 100644 index 00000000000..d653bbe2a50 --- /dev/null +++ b/org.eclipse.xtext.common.types/src/org/eclipse/xtext/common/types/impl/JvmGenericClassImplCustom.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2023 itemis AG (http://www.itemis.eu) and others. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.xtext.common.types.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.xtext.common.types.JvmTypeReference; + +/** + * The implementation ensures that the classToExtend and + * interfacesToImplementare consistent with the superTypes. + * + * In particular, if a the class to extend is set (respectively, unset) the + * superTypes will contain it (respectively, will not contain it). Similarly, + * for interfaces to implement. If a type is added to superTypes directly, the + * class to extend and the interfaces to implement will not be touched. If a + * type is removed from superTypes, if it corresponds to a class to extend or + * interface to implement, the classToExtend or the interfacesToImplement will + * be updated accordingly. + * + * Note that superTypes is a container list, while interfacesToImplement is not. + * + * @author Lorenzo Bettini - Initial contribution and API + */ +public class JvmGenericClassImplCustom extends JvmGenericClassImpl { + + private List superTypesSnapshot = Collections.emptyList(); + private List interfacesToImplementSnapshot = Collections.emptyList(); + + @Override + public void setClassToExtend(JvmTypeReference newClassToExtend) { + JvmTypeReference oldClassToExtend = classToExtend; + super.setClassToExtend(newClassToExtend); + getSuperTypes().remove(oldClassToExtend); + if (newClassToExtend != null) { + getSuperTypes().add(newClassToExtend); + } + } + + @Override + public JvmTypeReference getClassToExtend() { + if (!getSuperTypes().contains(classToExtend)) { + // some one else removed it via superTypes API + super.setClassToExtend(null); + } + return super.getClassToExtend(); + } + + @Override + public EList getSuperTypes() { + var origSuperTypes = super.getSuperTypes(); + var origInterfacesToImplement = super.getInterfacesToImplement(); + if (!origInterfacesToImplement.equals(interfacesToImplementSnapshot)) { + // remove elements contained in the snapshot + origSuperTypes.removeAll(interfacesToImplementSnapshot); + // add all interfaces to implement + origSuperTypes.addAll(origInterfacesToImplement); + // update snapshot + interfacesToImplementSnapshot = + createSnapshot(origInterfacesToImplement); + } + return origSuperTypes; + } + + @Override + public EList getInterfacesToImplement() { + var origInterfacesToImplement = super.getInterfacesToImplement(); + var origSuperTypes = super.getSuperTypes(); + if (!superTypesSnapshot.equals(origSuperTypes)) { + // remove interfaces that are not in superTypes + // if they're not there, they have been removed through superTypes + origInterfacesToImplement.removeIf(e -> !origSuperTypes.contains(e)); + // update snapshot + superTypesSnapshot = + createSnapshot(origSuperTypes); + } + return origInterfacesToImplement; + } + + private List createSnapshot(EList origList) { + return new ArrayList<>(origList); + } +}