changeset 16787:9346cbeeded3

Added initial version of the graal graph nodes annotation processor.
author Christian Humer <christian.humer@gmail.com>
date Tue, 12 Aug 2014 17:21:06 +0200
parents 45c8f64978d6
children cf71dd00db68
files graal/com.oracle.graal.graph.processor/src/META-INF/services/javax.annotation.processing.Processor graal/com.oracle.graal.graph.processor/src/com/oracle/graal/graph/processor/GraphNode.java graal/com.oracle.graal.graph.processor/src/com/oracle/graal/graph/processor/GraphNodeGenerator.java graal/com.oracle.graal.graph.processor/src/com/oracle/graal/graph/processor/GraphNodeParser.java graal/com.oracle.graal.graph.processor/src/com/oracle/graal/graph/processor/GraphNodeProcessor.java mx/projects
diffstat 6 files changed, 298 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graph.processor/src/META-INF/services/javax.annotation.processing.Processor	Tue Aug 12 17:21:06 2014 +0200
@@ -0,0 +1,1 @@
+com.oracle.graal.graph.processor.GraphNodeProcessor
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graph.processor/src/com/oracle/graal/graph/processor/GraphNode.java	Tue Aug 12 17:21:06 2014 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.graph.processor;
+
+import javax.lang.model.element.*;
+
+import com.oracle.graal.graph.*;
+
+public class GraphNode {
+
+    private final NodeInfo nodeInfo;
+    private final TypeElement declaration;
+
+    public GraphNode(TypeElement type, NodeInfo nodeInfo) {
+        this.declaration = type;
+        this.nodeInfo = nodeInfo;
+    }
+
+    public NodeInfo getNodeInfo() {
+        return nodeInfo;
+    }
+
+    public TypeElement getDeclaration() {
+        return declaration;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graph.processor/src/com/oracle/graal/graph/processor/GraphNodeGenerator.java	Tue Aug 12 17:21:06 2014 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.graph.processor;
+
+import static com.oracle.truffle.dsl.processor.java.ElementUtils.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.lang.model.util.*;
+
+import com.oracle.truffle.dsl.processor.java.*;
+import com.oracle.truffle.dsl.processor.java.model.*;
+
+public class GraphNodeGenerator {
+
+    private final ProcessingEnvironment processingEnv;
+
+    public GraphNodeGenerator(ProcessingEnvironment processingEnv) {
+        this.processingEnv = processingEnv;
+    }
+
+    public ProcessingEnvironment getProcessingEnv() {
+        return processingEnv;
+    }
+
+    public CodeCompilationUnit process(GraphNode node) {
+        CodeCompilationUnit compilationUnit = new CodeCompilationUnit();
+
+        TypeElement typeElement = node.getDeclaration();
+        PackageElement packageElement = ElementUtils.findPackageElement(node.getDeclaration());
+
+        String newClassName = typeElement.getSimpleName().toString() + "Gen";
+        CodeTypeElement nodeGenElement = new CodeTypeElement(modifiers(), ElementKind.CLASS, packageElement, newClassName);
+
+        if (typeElement.getModifiers().contains(Modifier.ABSTRACT)) {
+            // we do not support implementation of abstract methods yet.
+            nodeGenElement.getModifiers().add(Modifier.ABSTRACT);
+        }
+
+        nodeGenElement.setSuperClass(typeElement.asType());
+
+        for (ExecutableElement constructor : ElementFilter.constructorsIn(typeElement.getEnclosedElements())) {
+            if (constructor.getModifiers().contains(Modifier.PRIVATE)) {
+                // ignore private constructors
+                continue;
+            }
+            nodeGenElement.add(createSuperConstructor(nodeGenElement, constructor));
+        }
+
+        nodeGenElement.add(createDummyExampleMethod());
+
+        compilationUnit.add(nodeGenElement);
+        return compilationUnit;
+    }
+
+    private CodeExecutableElement createSuperConstructor(TypeElement type, ExecutableElement element) {
+        CodeExecutableElement executable = CodeExecutableElement.clone(processingEnv, element);
+
+        // to create a constructor we have to set the return type to null.(TODO needs fix)
+        executable.setReturnType(null);
+        // we have to set the name manually otherwise <init> is inferred (TODO needs fix)
+        executable.setSimpleName(CodeNames.of(type.getSimpleName().toString()));
+
+        CodeTreeBuilder b = executable.createBuilder();
+        b.startStatement().startSuperCall();
+        for (VariableElement v : element.getParameters()) {
+            b.string(v.getSimpleName().toString());
+        }
+        b.end().end();
+
+        return executable;
+    }
+
+    public ExecutableElement createDummyExampleMethod() {
+        CodeExecutableElement method = new CodeExecutableElement(modifiers(Modifier.PROTECTED), ElementUtils.getType(processingEnv, int.class), "computeTheMeaningOfLife");
+
+        CodeTreeBuilder builder = method.createBuilder();
+        builder.string("// this method got partially evaluated").newLine();
+        builder.startReturn().string("42").end();
+
+        return method;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graph.processor/src/com/oracle/graal/graph/processor/GraphNodeParser.java	Tue Aug 12 17:21:06 2014 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.graph.processor;
+
+import java.lang.annotation.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+
+import com.oracle.graal.graph.*;
+
+public class GraphNodeParser {
+
+    private final ProcessingEnvironment processingEnv;
+
+    public GraphNodeParser(ProcessingEnvironment processingEnv) {
+        this.processingEnv = processingEnv;
+    }
+
+    protected GraphNode parse(TypeElement element, NodeInfo nodeInfo) {
+        if (element.getModifiers().contains(Modifier.FINAL)) {
+            // TODO fail?
+            return null;
+        }
+        return new GraphNode(element, nodeInfo);
+    }
+
+    public ProcessingEnvironment getProcessingEnv() {
+        return processingEnv;
+    }
+
+    public Class<? extends Annotation> getAnnotationType() {
+        return NodeInfo.class;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graph.processor/src/com/oracle/graal/graph/processor/GraphNodeProcessor.java	Tue Aug 12 17:21:06 2014 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.graph.processor;
+
+import java.util.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.graal.graph.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.java.*;
+import com.oracle.truffle.dsl.processor.java.model.*;
+import com.oracle.truffle.dsl.processor.java.transform.*;
+
+@SupportedSourceVersion(SourceVersion.RELEASE_8)
+@SupportedAnnotationTypes({"com.oracle.graal.graph.NodeInfo"})
+public class GraphNodeProcessor extends AbstractProcessor {
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        if (roundEnv.processingOver()) {
+            return false;
+        }
+
+        GraphNodeParser parser = new GraphNodeParser(processingEnv);
+        GraphNodeGenerator gen = new GraphNodeGenerator(processingEnv);
+
+        for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(parser.getAnnotationType())) {
+            if (annotatedElement.getKind() != ElementKind.CLASS) {
+                // TODO fail?
+                continue;
+            }
+
+            NodeInfo nodeInfo = annotatedElement.getAnnotation(NodeInfo.class);
+            if (nodeInfo == null) {
+                // TODO assert nodeInfo != null?
+                continue;
+            }
+
+            TypeElement typeElement = (TypeElement) annotatedElement;
+            GraphNode graphNode = parser.parse(typeElement, nodeInfo);
+            if (graphNode == null) {
+                // TODO fail?`
+                continue;
+            }
+
+            CodeCompilationUnit unit = gen.process(graphNode);
+            unit.setGeneratorElement(typeElement);
+
+            DeclaredType overrideType = (DeclaredType) ElementUtils.getType(processingEnv, Override.class);
+            DeclaredType unusedType = (DeclaredType) ElementUtils.getType(processingEnv, SuppressWarnings.class);
+            unit.accept(new GenerateOverrideVisitor(overrideType), null);
+            unit.accept(new FixWarningsVisitor(processingEnv, unusedType, overrideType), null);
+            unit.accept(new CodeWriter(processingEnv, typeElement), null);
+        }
+        return false;
+    }
+
+}
--- a/mx/projects	Tue Aug 12 17:21:06 2014 +0200
+++ b/mx/projects	Tue Aug 12 17:21:06 2014 +0200
@@ -350,6 +350,13 @@
 project@com.oracle.graal.graph@javaCompliance=1.8
 project@com.oracle.graal.graph@workingSets=Graal,Graph
 
+# graal.graph
+project@com.oracle.graal.graph.processor@subDir=graal
+project@com.oracle.graal.graph.processor@sourceDirs=src
+project@com.oracle.graal.graph.processor@dependencies=com.oracle.graal.graph,com.oracle.truffle.dsl.processor
+project@com.oracle.graal.graph.processor@javaCompliance=1.8
+project@com.oracle.graal.graph.processor@workingSets=Graal,Graph
+
 # graal.graph.test
 project@com.oracle.graal.graph.test@subDir=graal
 project@com.oracle.graal.graph.test@sourceDirs=src
@@ -477,7 +484,7 @@
 project@com.oracle.graal.nodes@dependencies=com.oracle.graal.graph,com.oracle.graal.api.replacements,com.oracle.graal.lir
 project@com.oracle.graal.nodes@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.nodes@javaCompliance=1.8
-project@com.oracle.graal.nodes@annotationProcessors=com.oracle.graal.replacements.verifier
+project@com.oracle.graal.nodes@annotationProcessors=com.oracle.graal.replacements.verifier,com.oracle.graal.graph.processor
 project@com.oracle.graal.nodes@workingSets=Graal,Graph
 
 # graal.nodes.test