From 5d200173a3db2a275ddf3d14f7c1ecbb55cd2e3d Mon Sep 17 00:00:00 2001 From: Panagiotis Kourouklidis <22411884+pkourouklidis@users.noreply.github.com> Date: Wed, 13 Nov 2024 13:16:31 +0000 Subject: [PATCH] Support EolNativeType and refactor isCompatible --- .../StringOperationContributor.java | 9 ++- .../eol/staticanalyser/EolStaticAnalyser.java | 9 ++- .../eol/staticanalyser/types/EolAnyType.java | 5 ++ .../staticanalyser/types/EolNativeType.java | 34 +++++++++ .../eol/staticanalyser/types/EolNoType.java | 5 ++ .../types/EolPrimitiveType.java | 8 +++ .../eol/staticanalyser/types/EolType.java | 70 ++++++++++++++----- .../scripts/RealOperationContributor.eol | 1 + 8 files changed, 114 insertions(+), 27 deletions(-) create mode 100644 plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolNativeType.java create mode 100644 tests/org.eclipse.epsilon.eol.staticanalyser.tests/src/org/eclipse/epsilon/eol/staticanalyser/tests/scripts/RealOperationContributor.eol diff --git a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/execute/operations/contributors/StringOperationContributor.java b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/execute/operations/contributors/StringOperationContributor.java index 357743546..3a8f5b3b8 100644 --- a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/execute/operations/contributors/StringOperationContributor.java +++ b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/execute/operations/contributors/StringOperationContributor.java @@ -11,7 +11,6 @@ import java.io.FileOutputStream; import java.io.StringWriter; -import java.util.Arrays; import java.util.List; import javax.xml.parsers.DocumentBuilderFactory; @@ -22,8 +21,8 @@ import javax.xml.transform.stream.StreamResult; import org.eclipse.epsilon.common.util.CollectionUtil; -import org.eclipse.epsilon.eol.types.EolPrimitiveType; -import org.eclipse.epsilon.eol.types.EolType; +import org.eclipse.epsilon.eol.staticanalyser.types.EolPrimitiveType; +import org.eclipse.epsilon.eol.staticanalyser.types.EolType; import org.w3c.dom.Document; import org.w3c.dom.Text; @@ -35,8 +34,8 @@ public boolean contributesTo(Object target) { } @Override - public List contributesToType() { - return Arrays.asList(EolPrimitiveType.String); + public EolType contributesToType() { + return EolPrimitiveType.String; } public Object toEnum() throws Exception { diff --git a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/EolStaticAnalyser.java b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/EolStaticAnalyser.java index 5756805ea..d5c2bed39 100644 --- a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/EolStaticAnalyser.java +++ b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/EolStaticAnalyser.java @@ -106,6 +106,7 @@ import org.eclipse.epsilon.eol.staticanalyser.types.EolCollectionType; import org.eclipse.epsilon.eol.staticanalyser.types.EolMapType; import org.eclipse.epsilon.eol.staticanalyser.types.EolModelElementType; +import org.eclipse.epsilon.eol.staticanalyser.types.EolNativeType; import org.eclipse.epsilon.eol.staticanalyser.types.EolNoType; import org.eclipse.epsilon.eol.staticanalyser.types.EolPrimitiveType; import org.eclipse.epsilon.eol.staticanalyser.types.EolType; @@ -719,7 +720,7 @@ public void visit(OperationCallExpression operationCallExpression) { for (IStaticOperation op: resolvedOperations) { EolType opContextType = op.getContextType(); if(contextType == opContextType || - isCompatible(opContextType, contextType) || + opContextType.isAncestorOf(contextType) || canBeCompatible(opContextType, contextType)) { temp.add(op); } @@ -755,7 +756,7 @@ public void visit(OperationCallExpression operationCallExpression) { for (EolType reqParamType : reqParamTypess) { EolType provParamType = getResolvedType(parameterExpressions.get(index)); index++; - if (!isCompatible(reqParamType, provParamType) + if (!reqParamType.isAncestorOf(provParamType) && !canBeCompatible(reqParamType, provParamType)) { compatible = false; break; @@ -1251,8 +1252,6 @@ public EolType javaClassToEolType(Class javaClass) { } else if (javaClass == Double.class || javaClass == double.class || javaClass == Float.class || javaClass == float.class) { return EolPrimitiveType.Real; - } else if (javaClass == Number.class) { - return new EolUnionType(EolPrimitiveType.Real, EolPrimitiveType.Integer); } else if (javaClass == boolean.class || javaClass == Boolean.class) { return EolPrimitiveType.Boolean; } else if (javaClass == java.util.Collection.class) { @@ -1264,7 +1263,7 @@ public EolType javaClassToEolType(Class javaClass) { } else if (javaClass == java.util.Map.class) { return EolMapType.Map; } else { - return EolAnyType.Instance; + return new EolNativeType(javaClass); } } diff --git a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolAnyType.java b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolAnyType.java index b3feedd59..fae1ce273 100644 --- a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolAnyType.java +++ b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolAnyType.java @@ -27,4 +27,9 @@ public String toString() { protected EolType getParentType() { return null; } + + @Override + public boolean isAncestorOf(EolType type) { + return true; + } } diff --git a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolNativeType.java b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolNativeType.java new file mode 100644 index 000000000..3249251fa --- /dev/null +++ b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolNativeType.java @@ -0,0 +1,34 @@ +package org.eclipse.epsilon.eol.staticanalyser.types; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class EolNativeType extends EolType { + + private Class javaClass; + + public EolNativeType(Class javaClass) { + this.javaClass = javaClass; + } + + @Override + public String getName() { + return "Native"; + } + + @Override + public String toString() { + return "Native<" + javaClass.getName() +">"; + } + + @Override + public List getParentTypes() { + if (javaClass == Object.class) { + return Collections.emptyList(); + }else { + return Arrays.asList(new EolNativeType(javaClass.getSuperclass())); + } + } + +} diff --git a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolNoType.java b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolNoType.java index d5c3d0bca..7d5790076 100644 --- a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolNoType.java +++ b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolNoType.java @@ -26,4 +26,9 @@ public EolType getParentType() { return null; } + @Override + public boolean isAncestorOf(EolType type){ + return false; + } + } diff --git a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolPrimitiveType.java b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolPrimitiveType.java index 38ef7430b..4caf83278 100644 --- a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolPrimitiveType.java +++ b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolPrimitiveType.java @@ -9,6 +9,9 @@ ******************************************************************************/ package org.eclipse.epsilon.eol.staticanalyser.types; +import java.util.Arrays; +import java.util.List; + public class EolPrimitiveType extends EolType { private Class clazz; @@ -38,4 +41,9 @@ public String getName() { public String toString() { return getName(); } + + @Override + public List getParentTypes() { + return Arrays.asList(EolAnyType.Instance, new EolNativeType(this.clazz)); + } } diff --git a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolType.java b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolType.java index 50094a127..0bbf23a9e 100644 --- a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolType.java +++ b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/types/EolType.java @@ -11,50 +11,86 @@ import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.Set; +import java.util.Stack; public abstract class EolType { - + private Set ancestorCache = null; + public abstract String getName(); - + public boolean isNot(EolType type) { return this != type && this != EolAnyType.Instance; } - + @Override public String toString() { return getName(); } - + @Override public int hashCode() { return Objects.hash(getName()); } - + @Override public boolean equals(Object other) { - if (this == other) return true; - if (other == null) return false; - - if (this.getClass() != other.getClass()) return false; - + if (this == other) + return true; + if (other == null) + return false; + + if (this.getClass() != other.getClass()) + return false; + EolType eolType = (EolType) other; - + return Objects.equals(this.getName(), eolType.getName()); } - + public List getParentTypes() { EolType parentType = getParentType(); - if (parentType == null) return Collections.emptyList(); - else return Arrays.asList(parentType); + if (parentType == null) + return Collections.emptyList(); + else + return Arrays.asList(parentType); } - + protected EolType getParentType() { return EolAnyType.Instance; } - - public List getChildrenTypes(){ + + public Set getAncestors() { + if (ancestorCache != null) { + return ancestorCache; + } + Set ancestors = new HashSet(); + + Stack stack = new Stack(); + stack.push(this); + while (!stack.isEmpty()) { + EolType currentNode = stack.pop(); + if (!ancestors.contains(currentNode)) { + ancestors.add(currentNode); + stack.addAll(currentNode.getParentTypes()); + } + } + + ancestorCache = ancestors; + return ancestors; + } + + public List getChildrenTypes() { return Collections.emptyList(); } + + public boolean isAncestorOf(EolType type) { + if (type.equals(EolNoType.Instance)) { + return false; + } + return type.getAncestors().contains(this); + } } diff --git a/tests/org.eclipse.epsilon.eol.staticanalyser.tests/src/org/eclipse/epsilon/eol/staticanalyser/tests/scripts/RealOperationContributor.eol b/tests/org.eclipse.epsilon.eol.staticanalyser.tests/src/org/eclipse/epsilon/eol/staticanalyser/tests/scripts/RealOperationContributor.eol new file mode 100644 index 000000000..7a59822e4 --- /dev/null +++ b/tests/org.eclipse.epsilon.eol.staticanalyser.tests/src/org/eclipse/epsilon/eol/staticanalyser/tests/scripts/RealOperationContributor.eol @@ -0,0 +1 @@ +/*Native*/1.1.abs(); \ No newline at end of file