diff graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java @ 7502:6343a09b2ec1

Codegen operation generation is inferred from the node type hierarchy.
author Christian Humer <christian.humer@gmail.com>
date Fri, 18 Jan 2013 13:28:12 +0100
parents a748e4d44694
children 5e3d1a68664e
line wrap: on
line diff
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java	Thu Jan 17 17:21:16 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java	Fri Jan 18 13:28:12 2013 +0100
@@ -29,18 +29,41 @@
 
 import javax.lang.model.element.*;
 import javax.lang.model.type.*;
+import javax.lang.model.util.*;
 
 import com.oracle.truffle.codegen.processor.*;
 import com.oracle.truffle.codegen.processor.template.ParameterSpec.Cardinality;
 
-public abstract class TemplateMethodParser<E extends TemplateMethod> {
+public abstract class TemplateMethodParser<T extends Template, E extends TemplateMethod> {
 
     private final ProcessorContext context;
 
-    public TemplateMethodParser(ProcessorContext context) {
+    protected final T template;
+
+    private boolean emitErrors = true;
+    private boolean parseNullOnError = true;
+
+    public TemplateMethodParser(ProcessorContext context, T template) {
+        this.template = template;
         this.context = context;
     }
 
+    public boolean isEmitErrors() {
+        return emitErrors;
+    }
+
+    public void setParseNullOnError(boolean nullOnError) {
+        this.parseNullOnError = nullOnError;
+    }
+
+    public boolean isParseNullOnError() {
+        return parseNullOnError;
+    }
+
+    public void setEmitErrors(boolean emitErrors) {
+        this.emitErrors = emitErrors;
+    }
+
     public ProcessorContext getContext() {
         return context;
     }
@@ -49,9 +72,49 @@
 
     public abstract E create(TemplateMethod method);
 
-    public abstract Class<? extends Annotation> getAnnotationType();
+    public abstract boolean isParsable(ExecutableElement method);
+
+    public Class<? extends Annotation> getAnnotationType() {
+        return null;
+    }
+
+    public final List<E> parse(List<? extends Element> elements) {
+        List<ExecutableElement> methods = new ArrayList<>();
+        methods.addAll(ElementFilter.methodsIn(elements));
+
+        List<E> parsedMethods = new ArrayList<>();
+        boolean valid = true;
+        for (ExecutableElement method : methods) {
+            if (!isParsable(method)) {
+                continue;
+            }
 
-    public final E parse(ExecutableElement method, AnnotationMirror annotation, Template template) {
+            Class<? extends Annotation> annotationType = getAnnotationType();
+            AnnotationMirror mirror = null;
+            if (annotationType != null) {
+                mirror = Utils.findAnnotationMirror(getContext().getEnvironment(), method, annotationType);
+            }
+
+            if (method.getModifiers().contains(Modifier.PRIVATE)) {
+                getContext().getLog().error(method, "Method must not be private.");
+                valid = false;
+                continue;
+            }
+
+            E parsedMethod = parse(method, mirror);
+            if (parsedMethod != null) {
+                parsedMethods.add(parsedMethod);
+            } else {
+                valid = false;
+            }
+        }
+        if (!valid && parseNullOnError) {
+            return null;
+        }
+        return parsedMethods;
+    }
+
+    private E parse(ExecutableElement method, AnnotationMirror annotation) {
         MethodSpec methodSpecification = createSpecification(method, annotation);
         if (methodSpecification == null) {
             return null;
@@ -63,13 +126,15 @@
 
         ActualParameter returnTypeMirror = resolveTypeMirror(returnTypeSpec, method.getReturnType(), template);
         if (returnTypeMirror == null) {
-            String expectedReturnType = createTypeSignature(returnTypeSpec, true);
-            String actualReturnType = Utils.getSimpleName(method.getReturnType());
+            if (isEmitErrors()) {
+                String expectedReturnType = createTypeSignature(returnTypeSpec, true);
+                String actualReturnType = Utils.getSimpleName(method.getReturnType());
 
-            String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
-                            createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
+                String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
+                                createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
 
-            context.getLog().error(method, annotation, message);
+                context.getLog().error(method, annotation, message);
+            }
             return null;
         }
 
@@ -93,13 +158,15 @@
                     specification = null;
                     continue;
                 } else if (!specification.isOptional()) {
-                    // non option type specification found -> argument missing
-                    String expectedType = createTypeSignature(specification, false);
+                    if (isEmitErrors()) {
+                        // non option type specification found -> argument missing
+                        String expectedType = createTypeSignature(specification, false);
 
-                    String message = String.format("Missing argument \"%s\".\nExpected signature: \n %s", expectedType,
-                                    createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
+                        String message = String.format("Missing argument \"%s\".\nExpected signature: \n %s", expectedType,
+                                        createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
 
-                    context.getLog().error(method, message);
+                        context.getLog().error(method, message);
+                    }
                     return null;
                 } else {
                     // specification is optional -> continue
@@ -116,13 +183,15 @@
                     continue;
                 }
 
-                String expectedReturnType = createTypeSignature(specification, false);
-                String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName();
+                if (isEmitErrors()) {
+                    String expectedReturnType = createTypeSignature(specification, false);
+                    String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName();
 
-                String message = String.format("The provided argument type \"%s\" does not match expected type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
-                                createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
+                    String message = String.format("The provided argument type \"%s\" does not match expected type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
+                                    createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
 
-                context.getLog().error(parameter, message);
+                    context.getLog().error(parameter, message);
+                }
                 return null;
             }
 
@@ -136,16 +205,18 @@
 
         if (variableIterator.hasNext()) {
             parameter = variableIterator.next();
-            String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName();
-            String message = String.format("No argument expected but found \"%s\".\nExpected signature: \n %s", actualReturnType,
-                            createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
+            if (isEmitErrors()) {
+                String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName();
+                String message = String.format("No argument expected but found \"%s\".\nExpected signature: \n %s", actualReturnType,
+                                createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
 
-            context.getLog().error(parameter, message);
+                context.getLog().error(parameter, message);
+            }
             return null;
         }
 
         ActualParameter[] paramMirrors = resolvedMirrors.toArray(new ActualParameter[resolvedMirrors.size()]);
-        return create(new TemplateMethod(methodSpecification, method, annotation, returnTypeMirror, paramMirrors));
+        return create(new TemplateMethod(template, methodSpecification, method, annotation, returnTypeMirror, paramMirrors));
     }
 
     private ActualParameter resolveTypeMirror(ParameterSpec specification, TypeMirror mirror, Template typeSystem) {