# HG changeset patch # User Christian Humer # Date 1407856866 -7200 # Node ID 9346cbeeded397367a269c58432d72f67eeb9523 # Parent 45c8f64978d6170d32d6aee4b68ed76475fd6dc9 Added initial version of the graal graph nodes annotation processor. diff -r 45c8f64978d6 -r 9346cbeeded3 graal/com.oracle.graal.graph.processor/src/META-INF/services/javax.annotation.processing.Processor --- /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 diff -r 45c8f64978d6 -r 9346cbeeded3 graal/com.oracle.graal.graph.processor/src/com/oracle/graal/graph/processor/GraphNode.java --- /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; + } + +} diff -r 45c8f64978d6 -r 9346cbeeded3 graal/com.oracle.graal.graph.processor/src/com/oracle/graal/graph/processor/GraphNodeGenerator.java --- /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 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; + } + +} diff -r 45c8f64978d6 -r 9346cbeeded3 graal/com.oracle.graal.graph.processor/src/com/oracle/graal/graph/processor/GraphNodeParser.java --- /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 getAnnotationType() { + return NodeInfo.class; + } + +} diff -r 45c8f64978d6 -r 9346cbeeded3 graal/com.oracle.graal.graph.processor/src/com/oracle/graal/graph/processor/GraphNodeProcessor.java --- /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 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; + } + +} diff -r 45c8f64978d6 -r 9346cbeeded3 mx/projects --- 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