comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ClassElementFactory.java @ 7291:a748e4d44694

Truffle API to specify type-specalized Node classes; annotation processor for automatic code generation of the type-specialized Node classes during the build process
author Christian Humer <christian.humer@gmail.com>
date Fri, 21 Dec 2012 10:44:31 -0800
parents
children 6343a09b2ec1
comparison
equal deleted inserted replaced
7290:a81db08fe930 7291:a748e4d44694
1 /*
2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package com.oracle.truffle.codegen.processor.template;
24
25 import static com.oracle.truffle.codegen.processor.Utils.*;
26 import static javax.lang.model.element.Modifier.*;
27
28 import java.util.*;
29
30 import javax.lang.model.element.*;
31 import javax.lang.model.type.*;
32 import javax.lang.model.util.*;
33
34 import com.oracle.truffle.api.codegen.*;
35 import com.oracle.truffle.codegen.processor.*;
36 import com.oracle.truffle.codegen.processor.ast.*;
37
38 public abstract class ClassElementFactory<M> extends CodeElementFactory<M> {
39
40 public ClassElementFactory(ProcessorContext context) {
41 super(context);
42 }
43
44 @Override
45 protected abstract CodeTypeElement create(M m);
46
47 protected CodeExecutableElement createConstructorUsingFields(Set<Modifier> modifiers, CodeTypeElement clazz) {
48 CodeExecutableElement method = new CodeExecutableElement(modifiers, null, clazz.getSimpleName().toString());
49 CodeTreeBuilder builder = method.createBuilder();
50 TypeElement superClass = fromTypeMirror(clazz.getSuperclass());
51 ExecutableElement constructor = findConstructor(superClass);
52 if (constructor != null && constructor.getParameters().size() > 0) {
53 builder.startStatement();
54 builder.startSuperCall();
55 for (VariableElement parameter : constructor.getParameters()) {
56 method.addParameter(new CodeVariableElement(parameter.asType(), parameter.getSimpleName().toString()));
57 builder.string(parameter.getSimpleName().toString());
58 }
59 builder.end(); // super
60 builder.end(); // statement
61 }
62
63 for (VariableElement field : clazz.getFields()) {
64 if (field.getModifiers().contains(STATIC)) {
65 continue;
66 }
67 String fieldName = field.getSimpleName().toString();
68 method.addParameter(new CodeVariableElement(field.asType(), fieldName));
69 builder.startStatement();
70 builder.string("this.");
71 builder.string(fieldName);
72 builder.string(" = ");
73 if (isAssignable(field.asType(), getContext().getTruffleTypes().getNode())) {
74 builder.string("adoptChild(").string(fieldName).string(")");
75 } else {
76 builder.string(fieldName);
77 }
78 builder.end(); // statement
79 }
80
81 return method;
82 }
83
84 private static ExecutableElement findConstructor(TypeElement clazz) {
85 List<ExecutableElement> constructors = ElementFilter.constructorsIn(clazz.getEnclosedElements());
86 if (constructors.isEmpty()) {
87 return null;
88 } else {
89 return constructors.get(0);
90 }
91 }
92
93 protected CodeTypeElement createClass(Template model, Set<Modifier> modifiers, String simpleName, TypeMirror superType, boolean enumType) {
94 TypeElement templateType = model.getTemplateType();
95
96 PackageElement pack = getContext().getEnvironment().getElementUtils().getPackageOf(templateType);
97 CodeTypeElement clazz = new CodeTypeElement(modifiers, enumType ? ElementKind.ENUM : ElementKind.CLASS, pack, simpleName);
98 TypeMirror resolvedSuperType = superType;
99 if (resolvedSuperType == null) {
100 resolvedSuperType = getContext().getType(Object.class);
101 }
102 clazz.setSuperClass(resolvedSuperType);
103
104 CodeAnnotationMirror generatedByAnnotation = new CodeAnnotationMirror((DeclaredType) getContext().getType(GeneratedBy.class));
105 generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("value"), new CodeAnnotationValue(templateType.asType()));
106 clazz.addAnnotationMirror(generatedByAnnotation);
107
108 context.registerType(model.getTemplateType(), clazz.asType());
109
110 return clazz;
111 }
112 }