diff graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MethodSpec.java @ 8595:8a1115c92271

Implemented codegen guard definitions can now omit unused parameters.
author Christian Humer <christian.humer@gmail.com>
date Mon, 01 Apr 2013 21:43:20 +0200
parents 703c09f8640c
children 61ba6fc21ba4
line wrap: on
line diff
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MethodSpec.java	Mon Apr 01 12:19:15 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MethodSpec.java	Mon Apr 01 21:43:20 2013 +0200
@@ -26,33 +26,74 @@
 
 import javax.lang.model.type.*;
 
+import com.oracle.truffle.codegen.processor.*;
+import com.oracle.truffle.codegen.processor.template.ParameterSpec.Cardinality;
+
 public class MethodSpec {
 
-    private final List<TypeMirror> implicitTypes;
+    private final List<TypeMirror> implicitRequiredTypes = new ArrayList<>();
 
     private final ParameterSpec returnType;
-    private final List<ParameterSpec> parameters;
+    private final List<ParameterSpec> optional = new ArrayList<>();
+    private final List<ParameterSpec> required = new ArrayList<>();
+
+    private boolean variableRequiredArguments;
+    private List<TypeDef> typeDefinitions;
 
-    public MethodSpec(List<TypeMirror> prefixTypes, ParameterSpec returnType, List<ParameterSpec> parameters) {
-        this.implicitTypes = prefixTypes;
+    public MethodSpec(ParameterSpec returnType) {
         this.returnType = returnType;
-        this.parameters = parameters;
+    }
+
+    public void setVariableRequiredArguments(boolean variableArguments) {
+        this.variableRequiredArguments = variableArguments;
     }
 
-    public List<TypeMirror> getImplicitTypes() {
-        return implicitTypes;
+    public boolean isVariableRequiredArguments() {
+        return variableRequiredArguments;
+    }
+
+    public void addImplicitRequiredType(TypeMirror type) {
+        this.implicitRequiredTypes.add(type);
+    }
+
+    public void addOptional(ParameterSpec spec) {
+        optional.add(spec);
+    }
+
+    public void addRequired(ParameterSpec spec) {
+        required.add(spec);
+    }
+
+    public List<TypeMirror> getImplicitRequiredTypes() {
+        return implicitRequiredTypes;
     }
 
     public ParameterSpec getReturnType() {
         return returnType;
     }
 
-    public List<ParameterSpec> getParameters() {
-        return parameters;
+    public List<ParameterSpec> getRequired() {
+        return required;
+    }
+
+    public List<ParameterSpec> getOptional() {
+        return optional;
+    }
+
+    public void makeTypeDefinitions() {
+
+    }
+
+    public List<ParameterSpec> getAll() {
+        List<ParameterSpec> specs = new ArrayList<>();
+        specs.add(getReturnType());
+        specs.addAll(getOptional());
+        specs.addAll(getRequired());
+        return specs;
     }
 
     public ParameterSpec findParameterSpec(String name) {
-        for (ParameterSpec spec : parameters) {
+        for (ParameterSpec spec : getAll()) {
             if (spec.getName().equals(name)) {
                 return spec;
             }
@@ -60,4 +101,131 @@
         return null;
     }
 
+    public void applyTypeDefinitions(String prefix) {
+        this.typeDefinitions = createTypeDefinitions(prefix);
+    }
+
+    private List<TypeDef> createTypeDefinitions(String prefix) {
+        List<TypeDef> typeDefs = new ArrayList<>();
+
+        int defIndex = 0;
+        for (ParameterSpec spec : getAll()) {
+            List<TypeMirror> allowedTypes = spec.getAllowedTypes();
+            List<TypeMirror> types = spec.getAllowedTypes();
+            if (types != null && allowedTypes.size() > 1) {
+                TypeDef foundDef = null;
+                for (TypeDef def : typeDefs) {
+                    if (allowedTypes.equals(def.getTypes())) {
+                        foundDef = def;
+                        break;
+                    }
+                }
+                if (foundDef == null) {
+                    foundDef = new TypeDef(types, prefix + defIndex);
+                    typeDefs.add(foundDef);
+                    defIndex++;
+                }
+
+                spec.setTypeDefinition(foundDef);
+            }
+        }
+
+        return typeDefs;
+    }
+
+    public String toSignatureString(String methodName) {
+        StringBuilder b = new StringBuilder();
+        b.append("    ");
+        b.append(createTypeSignature(returnType, true));
+
+        b.append(" ");
+        b.append(methodName);
+        b.append("(");
+
+        String sep = "";
+
+        for (ParameterSpec optionalSpec : getOptional()) {
+            b.append(sep);
+            b.append("[");
+            b.append(createTypeSignature(optionalSpec, false));
+            b.append("]");
+            sep = ", ";
+        }
+
+        for (ParameterSpec requiredSpec : getRequired()) {
+            b.append(sep);
+            if (requiredSpec.getCardinality() == Cardinality.MULTIPLE) {
+                b.append("{");
+            }
+            b.append(createTypeSignature(requiredSpec, false));
+            if (requiredSpec.getCardinality() == Cardinality.MULTIPLE) {
+                b.append("}");
+            }
+            sep = ", ";
+        }
+
+        b.append(")");
+
+        if (typeDefinitions != null && !typeDefinitions.isEmpty()) {
+            b.append("\n\n");
+
+            String lineSep = "";
+            for (TypeDef def : typeDefinitions) {
+                b.append(lineSep);
+                b.append("    <").append(def.getName()).append(">");
+                b.append(" = {");
+                String separator = "";
+                for (TypeMirror type : def.getTypes()) {
+                    b.append(separator).append(Utils.getSimpleName(type));
+                    separator = ", ";
+                }
+                b.append("}");
+                lineSep = "\n";
+
+            }
+        }
+        return b.toString();
+    }
+
+    private static String createTypeSignature(ParameterSpec spec, boolean typeOnly) {
+        StringBuilder builder = new StringBuilder();
+        TypeDef foundTypeDef = spec.getTypeDefinition();
+        if (foundTypeDef != null) {
+            builder.append("<" + foundTypeDef.getName() + ">");
+        } else if (spec.getAllowedTypes().size() >= 1) {
+            builder.append(Utils.getSimpleName(spec.getAllowedTypes().get(0)));
+        } else {
+            builder.append("void");
+        }
+        if (!typeOnly) {
+            builder.append(" ");
+            builder.append(spec.getName());
+        }
+        return builder.toString();
+    }
+
+    @Override
+    public String toString() {
+        return toSignatureString("methodName");
+    }
+
+    static class TypeDef {
+
+        private final List<TypeMirror> types;
+        private final String name;
+
+        public TypeDef(List<TypeMirror> types, String name) {
+            this.types = types;
+            this.name = name;
+        }
+
+        public List<TypeMirror> getTypes() {
+            return types;
+        }
+
+        public String getName() {
+            return name;
+        }
+    }
+
 }