comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java @ 16755:bd28da642eea

Truffle-DSL: Several new features implemented: Implementation of a new code generation layout which shares code between generated nodes. Declaration order of specializations is now used as specialization order. Specializations do no longer perform fallthrough on respecialization, they now always respecialize from the first specialization. Implemented support for contains relations between specializations. Improved reachability error messages. Preliminary support for @Implies.
author Christian Humer <christian.humer@gmail.com>
date Mon, 11 Aug 2014 15:53:05 +0200
parents 25ecb47a6d0e
children
comparison
equal deleted inserted replaced
16754:55fd5be68a52 16755:bd28da642eea
27 import javax.lang.model.element.*; 27 import javax.lang.model.element.*;
28 import javax.tools.Diagnostic.Kind; 28 import javax.tools.Diagnostic.Kind;
29 29
30 import com.oracle.truffle.dsl.processor.*; 30 import com.oracle.truffle.dsl.processor.*;
31 31
32 public abstract class MessageContainer { 32 public abstract class MessageContainer implements Iterable<MessageContainer> {
33 33
34 private final List<Message> messages = new ArrayList<>(); 34 private final List<Message> messages = new ArrayList<>();
35 35
36 public final void addWarning(String text, Object... params) { 36 public final void addWarning(String text, Object... params) {
37 getMessages().add(new Message(null, this, String.format(text, params), Kind.WARNING)); 37 getMessages().add(new Message(null, this, String.format(text, params), Kind.WARNING));
38 } 38 }
39 39
40 public final void addWarning(AnnotationValue value, String text, Object... params) {
41 getMessages().add(new Message(value, this, String.format(text, params), Kind.WARNING));
42 }
43
40 public final void addError(String text, Object... params) { 44 public final void addError(String text, Object... params) {
41 addError(null, text, params); 45 addError(null, text, params);
42 } 46 }
43 47
44 public final void addError(AnnotationValue value, String text, Object... params) { 48 public final void addError(AnnotationValue value, String text, Object... params) {
49 return Collections.emptyList(); 53 return Collections.emptyList();
50 } 54 }
51 55
52 public abstract Element getMessageElement(); 56 public abstract Element getMessageElement();
53 57
54 public final void emitMessages(ProcessorContext context, TypeElement baseElement, Log log) { 58 public MessageContainer getBaseContainer() {
55 emitMessagesImpl(context, baseElement, log, new HashSet<MessageContainer>(), null); 59 return null;
56 } 60 }
57 61
58 private void emitMessagesImpl(ProcessorContext context, TypeElement baseElement, Log log, Set<MessageContainer> visitedSinks, List<Message> verifiedMessages) { 62 public Iterator<MessageContainer> iterator() {
63 return findChildContainers().iterator();
64 }
65
66 public final void emitMessages(ProcessorContext context, Log log) {
67 emitMessagesImpl(context, log, new HashSet<MessageContainer>(), null);
68 }
69
70 private void emitMessagesImpl(ProcessorContext context, Log log, Set<MessageContainer> visitedSinks, List<Message> verifiedMessages) {
59 List<Message> childMessages; 71 List<Message> childMessages;
60 if (verifiedMessages == null) { 72 if (verifiedMessages == null) {
61 childMessages = collectMessagesWithElementChildren(new HashSet<MessageContainer>(), getMessageElement()); 73 childMessages = collectMessagesWithElementChildren(new HashSet<MessageContainer>(), getMessageElement());
62 } else { 74 } else {
63 childMessages = verifiedMessages; 75 childMessages = verifiedMessages;
64 } 76 }
65 verifyExpectedMessages(context, log, childMessages); 77 verifyExpectedMessages(context, log, childMessages);
66 78
67 for (int i = getMessages().size() - 1; i >= 0; i--) { 79 for (int i = getMessages().size() - 1; i >= 0; i--) {
68 emitDefault(context, baseElement, log, getMessages().get(i)); 80 emitDefault(context, log, getMessages().get(i));
69 } 81 }
70 82
71 for (MessageContainer sink : findChildContainers()) { 83 for (MessageContainer sink : findChildContainers()) {
72 if (visitedSinks.contains(sink)) { 84 if (visitedSinks.contains(sink)) {
73 continue; 85 continue;
74 } 86 }
75 87
76 visitedSinks.add(sink); 88 visitedSinks.add(sink);
77 if (sink.getMessageElement() == this.getMessageElement()) { 89 if (sink.getMessageElement() == this.getMessageElement()) {
78 sink.emitMessagesImpl(context, baseElement, log, visitedSinks, childMessages); 90 sink.emitMessagesImpl(context, log, visitedSinks, childMessages);
79 } else { 91 } else {
80 sink.emitMessagesImpl(context, baseElement, log, visitedSinks, null); 92 sink.emitMessagesImpl(context, log, visitedSinks, null);
81 } 93 }
82 } 94 }
83 } 95 }
84 96
85 private List<Message> collectMessagesWithElementChildren(Set<MessageContainer> visitedSinks, Element e) { 97 private List<Message> collectMessagesWithElementChildren(Set<MessageContainer> visitedSinks, Element e) {
113 } 125 }
114 } 126 }
115 } 127 }
116 } 128 }
117 129
118 private void emitDefault(ProcessorContext context, TypeElement baseType, Log log, Message message) { 130 private void emitDefault(ProcessorContext context, Log log, Message message) {
119 Kind kind = message.getKind(); 131 Kind kind = message.getKind();
120 132
121 Element messageElement = getMessageElement(); 133 Element messageElement = getMessageElement();
122 AnnotationMirror messageAnnotation = getMessageAnnotation(); 134 AnnotationMirror messageAnnotation = getMessageAnnotation();
123 AnnotationValue messageValue = getMessageAnnotationValue(); 135 AnnotationValue messageValue = getMessageAnnotationValue();
124 if (message.getAnnotationValue() != null) { 136 if (message.getAnnotationValue() != null) {
125 messageValue = message.getAnnotationValue(); 137 messageValue = message.getAnnotationValue();
126 } 138 }
127 139
128 String text = message.getText(); 140 String text = message.getText();
129
130 TypeElement rootEnclosing = Utils.findRootEnclosingType(getMessageElement());
131 TypeElement baseEnclosing = Utils.findRootEnclosingType(baseType);
132 if (rootEnclosing == null || !Utils.typeEquals(baseEnclosing.asType(), rootEnclosing.asType())) {
133 // redirect message
134 MessageContainer original = message.getOriginalContainer();
135 messageElement = baseType;
136 messageAnnotation = null;
137 messageValue = null;
138 text = wrapText(original.getMessageElement(), original.getMessageAnnotation(), message.getText());
139 }
140 141
141 TypeElement expectError = context.getTruffleTypes().getExpectError(); 142 TypeElement expectError = context.getTruffleTypes().getExpectError();
142 if (expectError != null) { 143 if (expectError != null) {
143 AnnotationMirror mirror = Utils.findAnnotationMirror(messageElement.getAnnotationMirrors(), expectError); 144 AnnotationMirror mirror = Utils.findAnnotationMirror(messageElement.getAnnotationMirrors(), expectError);
144 if (mirror != null) { 145 if (mirror != null) {
163 } 164 }
164 165
165 log.message(kind, messageElement, messageAnnotation, messageValue, text); 166 log.message(kind, messageElement, messageAnnotation, messageValue, text);
166 } 167 }
167 168
168 private static String wrapText(Element element, AnnotationMirror mirror, String text) {
169 StringBuilder b = new StringBuilder();
170 if (element != null) {
171 b.append("Element " + element.toString());
172 }
173 if (mirror != null) {
174 b.append(" at annotation @" + Utils.getSimpleName(mirror.getAnnotationType()));
175 }
176
177 if (b.length() > 0) {
178 b.append(" is erroneous: ").append(text);
179 return b.toString();
180 } else {
181 return text;
182 }
183 }
184
185 public AnnotationMirror getMessageAnnotation() { 169 public AnnotationMirror getMessageAnnotation() {
186 return null; 170 return null;
187 } 171 }
188 172
189 public AnnotationValue getMessageAnnotationValue() { 173 public AnnotationValue getMessageAnnotationValue() {