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 af4db02d1..514a74b77 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 @@ -21,6 +21,9 @@ import javax.xml.transform.stream.StreamResult; import org.eclipse.epsilon.common.util.CollectionUtil; +import org.eclipse.epsilon.eol.execute.operations.OperationInfo; +import org.eclipse.epsilon.eol.types.EolPrimitiveType; +import org.eclipse.epsilon.eol.types.EolType; import org.w3c.dom.Document; import org.w3c.dom.Text; @@ -31,6 +34,11 @@ public boolean contributesTo(Object target) { return (target instanceof String || target instanceof Character); } + @Override + public EolType contributesToType() { + return EolPrimitiveType.String; + } + public Object toEnum() throws Exception { return getContext().getModelRepository().getEnumerationValue(getTarget() + ""); } @@ -57,6 +65,7 @@ public String firstToUpperCase() { return value.substring(0,1).toUpperCase() + value.substring(1, value.length()); } + @OperationInfo public String characterAt(int index) { String value = (String) getTarget(); return value.charAt(index) + ""; 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 18ee662b8..68066ae4b 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 @@ -1,5 +1,6 @@ package org.eclipse.epsilon.eol.staticanalyser; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -85,6 +86,7 @@ import org.eclipse.epsilon.eol.dom.XorOperatorExpression; import org.eclipse.epsilon.eol.staticanalyser.execute.context.FrameStack; import org.eclipse.epsilon.eol.execute.context.FrameType; +import org.eclipse.epsilon.eol.execute.operations.contributors.OperationContributor; import org.eclipse.epsilon.eol.staticanalyser.execute.context.Variable; import org.eclipse.epsilon.eol.m3.MetaClass; import org.eclipse.epsilon.eol.m3.Metamodel; @@ -731,7 +733,7 @@ public void visit(OperationCallExpression operationCallExpression) { // Number of parameters check temp = new ArrayList(); for (IStaticOperation op: resolvedOperations) { - List reqParams = op.getParameters(); + List reqParams = op.getParameterTypes(); if (reqParams.size() == parameterExpressions.size()) { temp.add(op); } @@ -746,14 +748,13 @@ public void visit(OperationCallExpression operationCallExpression) { temp = new ArrayList(); for (IStaticOperation op: resolvedOperations) { int index = 0; - List reqParams = op.getParameters(); + List reqParamTypess = op.getParameterTypes(); boolean compatible = true; - for (Parameter reqParam : reqParams) { - EolType reqParameter = getResolvedType(reqParam.getTypeExpression()); - EolType provParameter = getResolvedType(parameterExpressions.get(index)); + for (EolType reqParamType : reqParamTypess) { + EolType provParamType = getResolvedType(parameterExpressions.get(index)); index++; - if (!isCompatible(reqParameter, provParameter) - && !canBeCompatible(reqParameter, provParameter)) { + if (!isCompatible(reqParamType, provParamType) + && !canBeCompatible(reqParamType, provParamType)) { compatible = false; break; } @@ -1190,8 +1191,40 @@ public void preValidate(IEolModule imodule) { } module.getDeclaredOperations().forEach(o -> operationPreVisitor(o)); - module.getDeclaredOperations().forEach(o -> operations.add(new UserDefinedOperation(o))); + module.getDeclaredOperations().forEach(o -> operations.add(new SimpleOperation(o))); module.getDeclaredOperations().forEach(o -> o.accept(this)); + + //Parse builtin operations + List operationContributors = context.operationContributorRegistry.stream().collect(Collectors.toList()); + for(OperationContributor oc: operationContributors) { + EolType contextType = toStaticAnalyserType(oc.contributesToType()); + + for(Method m: oc.getClass().getDeclaredMethods()) { + List operationParameterTypes = new ArrayList(); + Class[] javaParameterTypes = m.getParameterTypes(); + for (Class javaParameterType : javaParameterTypes) { + operationParameterTypes.add(javaClassToEolType(javaParameterType)); + } + EolType returnType = javaClassToEolType(m.getReturnType()); + operations.add(new SimpleOperation(m.getName(), contextType, returnType, operationParameterTypes)); + } + } + } + + public EolType javaClassToEolType(Class javaClass) { + + if (javaClass == String.class || javaClass == char.class) { + return EolPrimitiveType.String; + } else if (javaClass == Integer.class || javaClass == int.class) { + return EolPrimitiveType.Integer; + } else if (javaClass == Double.class || javaClass == double.class || javaClass == Float.class + || javaClass == float.class) { + return EolPrimitiveType.Real; + } else if (javaClass == boolean.class || javaClass == Boolean.class) { + return EolPrimitiveType.Boolean; + } + + return EolAnyType.Instance; } public void mainValidate(IEolModule module) { diff --git a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/IStaticOperation.java b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/IStaticOperation.java index 30be3da74..bae41a0b4 100644 --- a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/IStaticOperation.java +++ b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/IStaticOperation.java @@ -2,7 +2,6 @@ import java.util.List; -import org.eclipse.epsilon.eol.dom.Parameter; import org.eclipse.epsilon.eol.staticanalyser.types.EolType; public interface IStaticOperation { @@ -11,7 +10,8 @@ public interface IStaticOperation { public EolType getContextType(); + //TODO: We might need the parameter types for this public EolType getReturnType(); - public List getParameters(); + public List getParameterTypes(); } diff --git a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/SimpleOperation.java b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/SimpleOperation.java new file mode 100644 index 000000000..9015499ab --- /dev/null +++ b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/SimpleOperation.java @@ -0,0 +1,54 @@ +package org.eclipse.epsilon.eol.staticanalyser; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.epsilon.eol.dom.Operation; +import org.eclipse.epsilon.eol.dom.Parameter; +import org.eclipse.epsilon.eol.staticanalyser.types.EolType; + +public class SimpleOperation implements IStaticOperation { + private String name; + private EolType contextType; + private EolType returnType; + private List parameterTypes; + + public SimpleOperation(Operation op) { + name = op.getName(); + contextType = (EolType) op.getData().get("contextType"); + returnType = (EolType) op.getData().get("returnType"); + this.parameterTypes = new ArrayList(); + for (Parameter p: op.getFormalParameters()) { + EolType parameterType = (EolType) p.getTypeExpression().getData().get("resolvedType"); + parameterTypes.add(parameterType); + } + } + + public SimpleOperation(String name, EolType contextType, EolType returnType, List parameterTypes) { + this.name = name; + this.contextType = contextType; + this.returnType = returnType; + this.parameterTypes = parameterTypes; + } + + @Override + public String getName() { + return name; + } + + @Override + public EolType getContextType() { + return contextType; + } + + @Override + public EolType getReturnType() { + return returnType; + } + + @Override + public List getParameterTypes() { + return parameterTypes; + } + +} diff --git a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/UserDefinedOperation.java b/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/UserDefinedOperation.java deleted file mode 100644 index a2369e699..000000000 --- a/plugins/org.eclipse.epsilon.eol.staticanalyser/src/org/eclipse/epsilon/eol/staticanalyser/UserDefinedOperation.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.eclipse.epsilon.eol.staticanalyser; - -import java.util.List; - -import org.eclipse.epsilon.eol.dom.Operation; -import org.eclipse.epsilon.eol.dom.Parameter; -import org.eclipse.epsilon.eol.staticanalyser.types.EolType; - -public class UserDefinedOperation implements IStaticOperation { - private String name; - private EolType contextType; - private EolType returnType; - private List parameters; - - public UserDefinedOperation(Operation op) { - name = op.getName(); - contextType = (EolType) op.getData().get("contextType"); - returnType = (EolType) op.getData().get("returnType"); - parameters = op.getFormalParameters(); - } - - @Override - public String getName() { - return name; - } - - @Override - public EolType getContextType() { - return contextType; - } - - @Override - public EolType getReturnType() { - return returnType; - } - - @Override - public List getParameters() { - return parameters; - } - -}