[541380] Ensure OCLstdlib metaclass is resolved and diagnosed
diff --git a/plugins/org.eclipse.ocl.xtext.base/src/org/eclipse/ocl/xtext/base/cs2as/CS2ASConversion.java b/plugins/org.eclipse.ocl.xtext.base/src/org/eclipse/ocl/xtext/base/cs2as/CS2ASConversion.java
index 597f51d..afef7b6 100644
--- a/plugins/org.eclipse.ocl.xtext.base/src/org/eclipse/ocl/xtext/base/cs2as/CS2ASConversion.java
+++ b/plugins/org.eclipse.ocl.xtext.base/src/org/eclipse/ocl/xtext/base/cs2as/CS2ASConversion.java
@@ -197,8 +197,12 @@
}
public void addError(@NonNull ElementCS csElement, /*@NonNull*/ String message, Object... bindings) {
- String boundMessage = NLS.bind(message, bindings);
INode node = NodeModelUtils.getNode(csElement);
+ addError(csElement, node, message, bindings);
+ }
+
+ public void addError(@NonNull ElementCS csElement, /*@NonNull*/ INode node, /*@NonNull*/ String message, Object... bindings) {
+ String boundMessage = NLS.bind(message, bindings);
Resource.Diagnostic resourceDiagnostic = new ValidationDiagnostic(node, boundMessage);
csElement.eResource().getErrors().add(resourceDiagnostic);
}
@@ -207,8 +211,12 @@
* @see org.eclipse.ocl.xtext.base.cs2as.DiagnosticHandler#addWarning(org.eclipse.ocl.xtext.basecs.ModelElementCS, java.lang.String, java.lang.Object)
*/
public void addWarning(@NonNull ModelElementCS csElement, /*@NonNull*/ String message, Object... bindings) {
- String boundMessage = NLS.bind(message, bindings);
INode node = NodeModelUtils.getNode(csElement);
+ addWarning(csElement, node, message, bindings);
+ }
+
+ public void addWarning(@NonNull ModelElementCS csElement, /*@NonNull*/ INode node, /*@NonNull*/ String message, Object... bindings) {
+ String boundMessage = NLS.bind(message, bindings);
Resource.Diagnostic resourceDiagnostic = new ValidationDiagnostic(node, boundMessage);
csElement.eResource().getWarnings().add(resourceDiagnostic);
}
diff --git a/plugins/org.eclipse.ocl.xtext.oclstdlib/src/org/eclipse/ocl/xtext/oclstdlib/cs2as/OCLstdlibCS2AS.java b/plugins/org.eclipse.ocl.xtext.oclstdlib/src/org/eclipse/ocl/xtext/oclstdlib/cs2as/OCLstdlibCS2AS.java
index d0f03ce..0e3c17c 100644
--- a/plugins/org.eclipse.ocl.xtext.oclstdlib/src/org/eclipse/ocl/xtext/oclstdlib/cs2as/OCLstdlibCS2AS.java
+++ b/plugins/org.eclipse.ocl.xtext.oclstdlib/src/org/eclipse/ocl/xtext/oclstdlib/cs2as/OCLstdlibCS2AS.java
@@ -53,32 +53,38 @@
}
}
+ @Deprecated /* @deprecated - pass String argument */
public @Nullable MetaclassNameCS lookUpMetaTypeName(@NonNull EObject csElement, /*@NonNull*/ EStructuralFeature eFeature) {
- Map<String, MetaclassNameCS> metaTypeNames2 = metaTypeNames;
+ List<INode> featureNodes = NodeModelUtils.findNodesForFeature(csElement, eFeature);
+ if ((featureNodes != null) && (featureNodes.size() > 0)) {
+ String metaclassNameText = NodeModelUtils.getTokenText(featureNodes.get(0));
+ MetaclassNameCS csMetaclassName = metaclassNameText != null ? getMetaclassName(metaclassNameText) : null;
+ csElement.eSet(eFeature, csMetaclassName);
+ return csMetaclassName;
+ }
+ return null;
+ }
+
+ public @Nullable MetaclassNameCS getMetaclassName(@NonNull String metaclassNameText) {
+ Map<@NonNull String, @NonNull MetaclassNameCS> metaTypeNames2 = metaTypeNames;
if (metaTypeNames2 == null) {
Resource metaTypeResource = new ResourceImpl(URI.createURI("internal_list;;//of_meta-type_names"));
- List<EObject> metaTypes = metaTypeResource.getContents();
+ List<@NonNull EObject> metaTypes = metaTypeResource.getContents();
metaTypeNames2 = metaTypeNames = new HashMap<>();
for (EClassifier eClassifier : PivotPackage.eINSTANCE.getEClassifiers()) {
if (eClassifier instanceof EClass) {
if (PivotPackage.Literals.CLASS.isSuperTypeOf((EClass) eClassifier)) {
- MetaclassNameCS metaTypeName = OCLstdlibCSFactory.eINSTANCE.createMetaclassNameCS();
+ MetaclassNameCS csMetaclassName = OCLstdlibCSFactory.eINSTANCE.createMetaclassNameCS();
String name = eClassifier.getName();
- metaTypeName.setName(name);
- metaTypeNames2.put(name, metaTypeName);
- metaTypes.add(metaTypeName); // Avoid detection of orphans by EnvironmentView.addElement()
+ assert name != null;
+ csMetaclassName.setName(name);
+ metaTypeNames2.put(name, csMetaclassName);
+ metaTypes.add(csMetaclassName); // Avoid detection of orphans by EnvironmentView.addElement()
}
}
}
}
- List<INode> featureNodes = NodeModelUtils.findNodesForFeature(csElement, eFeature);
- if ((featureNodes != null) && (featureNodes.size() > 0)) {
- String metaTypeNameText = NodeModelUtils.getTokenText(featureNodes.get(0));
- MetaclassNameCS metaTypeName = metaTypeNames2.get(metaTypeNameText);
- csElement.eSet(eFeature, metaTypeName);
- return metaTypeName;
- }
- return null;
+ return metaTypeNames2.get(metaclassNameText);
}
public OCLstdlibCS2AS(@NonNull EnvironmentFactoryInternal environmentFactory, @NonNull BaseCSResource csResource, @NonNull ASResource asResource) {
diff --git a/plugins/org.eclipse.ocl.xtext.oclstdlib/src/org/eclipse/ocl/xtext/oclstdlib/cs2as/OCLstdlibCSContainmentVisitor.java b/plugins/org.eclipse.ocl.xtext.oclstdlib/src/org/eclipse/ocl/xtext/oclstdlib/cs2as/OCLstdlibCSContainmentVisitor.java
index 14456d2..d51fb80 100644
--- a/plugins/org.eclipse.ocl.xtext.oclstdlib/src/org/eclipse/ocl/xtext/oclstdlib/cs2as/OCLstdlibCSContainmentVisitor.java
+++ b/plugins/org.eclipse.ocl.xtext.oclstdlib/src/org/eclipse/ocl/xtext/oclstdlib/cs2as/OCLstdlibCSContainmentVisitor.java
@@ -12,7 +12,9 @@
package org.eclipse.ocl.xtext.oclstdlib.cs2as;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
+import java.util.Map;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.resource.Resource;
@@ -52,6 +54,8 @@
import org.eclipse.ocl.xtext.oclstdlibcs.OCLstdlibCSPackage;
import org.eclipse.ocl.xtext.oclstdlibcs.PrecedenceCS;
import org.eclipse.ocl.xtext.oclstdlibcs.util.AbstractOCLstdlibCSContainmentVisitor;
+import org.eclipse.xtext.nodemodel.INode;
+import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
public class OCLstdlibCSContainmentVisitor extends AbstractOCLstdlibCSContainmentVisitor
{
@@ -74,7 +78,9 @@
@Override
public Continuation<?> visitLibClassCS(@NonNull LibClassCS csClass) {
- EClass eClass = null;
+ //
+ // Resolve explicit insstanceClass
+ //
String instanceClassName = null;
JavaClassCS implementation = csClass.getImplementation();
if ((implementation != null) && !implementation.eIsProxy()) {
@@ -88,39 +94,74 @@
context.addError(csClass, e.toString(), e);
}
}
- if (Boolean.class == instanceClass) {
- eClass = PivotPackage.Literals.BOOLEAN_TYPE;
+ //
+ // Resolve explicit metaType name object
+ //
+ MetaclassNameCS csMetaclassName = null;
+ List<INode> featureNodes = NodeModelUtils.findNodesForFeature(csClass, OCLstdlibCSPackage.Literals.LIB_CLASS_CS__METACLASS_NAME);
+ if ((featureNodes != null) && (featureNodes.size() > 0)) {
+ INode metaclassNameNode = featureNodes.get(0);
+ String metaTypeNameText = NodeModelUtils.getTokenText(metaclassNameNode);
+ if (metaTypeNameText != null) {
+ csMetaclassName = ((OCLstdlibCS2AS)context.getConverter()).getMetaclassName(metaTypeNameText);
+ }
+ if (csMetaclassName == null) {
+ context.addError(csClass, metaclassNameNode, "Unresolved metatype for ''{0}''", csClass);
+ }
}
- else if (String.class == instanceClass) {
- eClass = PivotPackage.Literals.PRIMITIVE_TYPE;
+ csClass.setMetaclassName(csMetaclassName);
+ //
+ // Resolve metaType EClass and provide a default implicit instanceClass
+ //
+ EClass eClass = null;
+ if ((csMetaclassName != null) && !csMetaclassName.eIsProxy()) {
+ String metaTypeName = csMetaclassName.getName();
+ eClass = (EClass) NameUtil.getENamedElement(PivotPackage.eINSTANCE.getEClassifiers(), metaTypeName);
+ if (eClass != null) {
+ instanceClass = eClass.getInstanceClass();
+ }
}
- else if (instanceClass != null) {
- if (NumberValue.class.isAssignableFrom(instanceClass)) {
+ //
+ // Provide a default metaType EClass
+ //
+ if (eClass == null) {
+ if (instanceClass == null) {
+ eClass = PivotPackage.Literals.CLASS;
+ }
+ else if (Boolean.class == instanceClass) {
+ eClass = PivotPackage.Literals.BOOLEAN_TYPE;
+ }
+ else if (String.class == instanceClass) {
+ eClass = PivotPackage.Literals.PRIMITIVE_TYPE;
+ }
+ else if (Collection.class.isAssignableFrom(instanceClass)) {
+ eClass = PivotPackage.Literals.COLLECTION_TYPE;
+ }
+ else if (Map.class.isAssignableFrom(instanceClass)) {
+ eClass = PivotPackage.Literals.MAP_TYPE;
+ }
+ else if (NumberValue.class.isAssignableFrom(instanceClass)) {
eClass = PivotPackage.Literals.PRIMITIVE_TYPE;
}
else if (Number.class.isAssignableFrom(instanceClass)) {
eClass = PivotPackage.Literals.PRIMITIVE_TYPE;
}
- }
- if (eClass == null) {
- MetaclassNameCS metaType = ((OCLstdlibCS2AS)context.getConverter()).lookUpMetaTypeName(csClass, OCLstdlibCSPackage.Literals.LIB_CLASS_CS__METACLASS_NAME);
- if ((metaType != null) && !metaType.eIsProxy()) {
- String metaTypeName = metaType.getName();
- eClass = (EClass) NameUtil.getENamedElement(PivotPackage.eINSTANCE.getEClassifiers(), metaTypeName);
- if (eClass != null) {
- instanceClass = eClass.getInstanceClass();
- }
- }
- if (eClass == null) {
+ else {
eClass = PivotPackage.Literals.CLASS;
}
}
+ //
+ // Provide a default instanceClass
+ //
if (instanceClass == null) {
instanceClass = Object.class;
}
if (instanceClassName == null) {
instanceClassName = instanceClass.getName();
}
+ //
+ // Finally refresh the class.
+ //
@SuppressWarnings("unchecked")
Class<org.eclipse.ocl.pivot.Class> eInstanceClass = (Class<org.eclipse.ocl.pivot.Class>)eClass.getInstanceClass();
if (eInstanceClass != null) {
diff --git a/tests/org.eclipse.ocl.examples.xtext.tests/models/oclstdlib/minimal.oclstdlib b/tests/org.eclipse.ocl.examples.xtext.tests/models/oclstdlib/minimal.oclstdlib
index 8aa716a..f24d172 100644
--- a/tests/org.eclipse.ocl.examples.xtext.tests/models/oclstdlib/minimal.oclstdlib
+++ b/tests/org.eclipse.ocl.examples.xtext.tests/models/oclstdlib/minimal.oclstdlib
@@ -6,7 +6,6 @@
type Collection(T) : CollectionType conformsTo OclAny {}
type Integer : PrimitiveType conformsTo Real {}
type Map(K,V) : MapType conformsTo OclAny {}
- type Metaclass(T) : Metaclass conformsTo OclAny {}
type OclAny : AnyType {
operation "="(object2 : OclAny) : Boolean;
}
diff --git a/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/EditTests.java b/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/EditTests.java
index 127c75e..e1c2fef 100644
--- a/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/EditTests.java
+++ b/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/EditTests.java
@@ -28,6 +28,7 @@
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.URIConverter;
+import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.ocl.common.internal.options.CommonOptions;
import org.eclipse.ocl.examples.xtext.tests.TestCaseAppender;
@@ -276,7 +277,6 @@
+ " type Collection(T) : CollectionType conformsTo OclAny {}\n"
+ " type Integer : PrimitiveType conformsTo Real => 'org.eclipse.ocl.pivot.values.IntegerValue' {}\n"
+ " type Map(K,V) : MapType conformsTo OclAny {}\n"
- + " type Metaclass(T) : Metaclass conformsTo OclAny {}\n"
+ " type OclAny : AnyType {\n"
// + " operation \"=\"(object2 : OclAny) : Boolean;\n"
+ " }\n"
@@ -317,6 +317,7 @@
//
// Change metatype.
//
+ @SuppressWarnings("unused")
String newDocument = testDocument.replace("type Boolean : PrimitiveType conformsTo", "type BooleanType conformsTo");
{
TestCaseAppender.INSTANCE.uninstall();
@@ -771,7 +772,7 @@
// Load and instrument test document
//
OCLInternal ocl1 = OCLInternal.newInstance(getProjectMap(), null);
- Resource ecoreResource = ClassUtil.nonNullEMF(ocl1.getResourceSet().getResource(ecoreURI, true));
+ XMLResource ecoreResource = (XMLResource) ClassUtil.nonNullEMF(ocl1.getResourceSet().getResource(ecoreURI, true));
assertNoResourceErrors("Ecore load", ecoreResource);
assertNoValidationErrors("Ecore load", ecoreResource);
ASResource asResource = ocl1.ecore2as(ecoreResource);
@@ -806,7 +807,7 @@
//
StringWriter writer = new StringWriter();
OutputStream outputStream = new URIConverter.WriteableOutputStream(writer, "UTF-8");
- ecoreResource.save(outputStream, XMIUtil.createSaveOptions());
+ ecoreResource.save(outputStream, XMIUtil.createSaveOptions(ecoreResource));
ecoreResource.unload();
InputStream inputStream = new URIConverter.ReadableInputStream(writer.toString().replace("tuttut", "tut"), "UTF-8");
ecoreResource.load(inputStream, null);