comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java @ 10597:79041ab43660

Truffle-DSL: API-change: Renamed truffle.api.codegen to truffle.api.dsl for all projects and packages.
author Christian Humer <christian.humer@gmail.com>
date Mon, 01 Jul 2013 20:58:32 +0200
parents
children 7a8835ec5e7d
comparison
equal deleted inserted replaced
10596:f43eb2f1bbbc 10597:79041ab43660
1 /*
2 * Copyright (c) 2012, 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.dsl.processor.node;
24
25 import java.lang.annotation.*;
26 import java.util.*;
27
28 import javax.lang.model.element.*;
29 import javax.lang.model.type.*;
30
31 import com.oracle.truffle.api.dsl.*;
32 import com.oracle.truffle.dsl.processor.*;
33 import com.oracle.truffle.dsl.processor.template.*;
34
35 public class CreateCastParser extends NodeMethodParser<CreateCastData> {
36
37 public CreateCastParser(ProcessorContext context, NodeData operation) {
38 super(context, operation);
39 }
40
41 @Override
42 public Class<? extends Annotation> getAnnotationType() {
43 return CreateCast.class;
44 }
45
46 @Override
47 public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
48 List<String> childNames = Utils.getAnnotationValueList(String.class, mirror, "value");
49 TypeMirror baseType = getContext().getTruffleTypes().getNode();
50 for (String childName : childNames) {
51 NodeChildData child = getNode().findChild(childName);
52 if (child != null) {
53 baseType = child.getOriginalType();
54 break;
55 }
56 }
57 MethodSpec spec = new MethodSpec(new InheritsParameterSpec(getContext(), "child", baseType));
58 addDefaultFieldMethodSpec(method, spec);
59 spec.addRequired(new ParameterSpec("castedChild", baseType)).setSignature(true);
60 return spec;
61 }
62
63 @Override
64 public CreateCastData create(TemplateMethod method) {
65 AnnotationMirror mirror = method.getMarkerAnnotation();
66 List<String> childNames = Utils.getAnnotationValueList(String.class, mirror, "value");
67 CreateCastData cast = new CreateCastData(method, childNames);
68 AnnotationValue value = Utils.getAnnotationValue(mirror, "value");
69 TypeMirror type = null;
70 if (childNames == null || childNames.isEmpty()) {
71 cast.addError(value, "No value specified but required.");
72 return cast;
73 }
74
75 for (String childName : childNames) {
76 NodeChildData child = getNode().findChild(childName);
77 if (child == null) {
78 // error
79 cast.addError(value, "Specified child '%s' not found.", childName);
80 continue;
81 }
82 if (type == null) {
83 type = child.getNodeType();
84 } else if (!Utils.typeEquals(type, child.getNodeType())) {
85 cast.addError(value, "All child nodes for a cast must have the same node type.");
86 continue;
87 }
88 }
89 return cast;
90 }
91
92 private static class InheritsParameterSpec extends ParameterSpec {
93
94 private final ProcessorContext context;
95
96 public InheritsParameterSpec(ProcessorContext context, String name, TypeMirror... allowedTypes) {
97 super(name, Arrays.asList(allowedTypes));
98 this.context = context;
99 }
100
101 @Override
102 public boolean matches(TypeMirror actualType) {
103 boolean found = false;
104 for (TypeMirror specType : getAllowedTypes()) {
105 if (Utils.isAssignable(context, actualType, specType)) {
106 found = true;
107 break;
108 }
109 }
110 return found;
111 }
112 }
113 }