Mercurial > hg > graal-jvmci-8
comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java @ 11467:43eab069ca9b
Truffle-DSL: improved error recovery of type systems and improved error testability infrastructure.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Thu, 29 Aug 2013 19:19:00 +0200 |
parents | 4830676526e3 |
children | f15d955897b7 |
comparison
equal
deleted
inserted
replaced
11466:4830676526e3 | 11467:43eab069ca9b |
---|---|
50 } | 50 } |
51 | 51 |
52 public abstract Element getMessageElement(); | 52 public abstract Element getMessageElement(); |
53 | 53 |
54 public final void emitMessages(ProcessorContext context, TypeElement baseElement, Log log) { | 54 public final void emitMessages(ProcessorContext context, TypeElement baseElement, Log log) { |
55 emitMessagesImpl(context, baseElement, log, new HashSet<MessageContainer>()); | 55 emitMessagesImpl(context, baseElement, log, new HashSet<MessageContainer>(), null); |
56 } | 56 } |
57 | 57 |
58 private void emitMessagesImpl(ProcessorContext context, TypeElement baseElement, Log log, Set<MessageContainer> visitedSinks) { | 58 private void emitMessagesImpl(ProcessorContext context, TypeElement baseElement, Log log, Set<MessageContainer> visitedSinks, List<Message> verifiedMessages) { |
59 List<Message> childMessages; | |
60 if (verifiedMessages == null) { | |
61 childMessages = collectMessagesWithElementChildren(new HashSet<MessageContainer>(), getMessageElement()); | |
62 } else { | |
63 childMessages = verifiedMessages; | |
64 } | |
65 verifyExpectedMessages(context, log, childMessages); | |
66 | |
67 for (Message message : getMessages()) { | |
68 emitDefault(context, baseElement, log, message); | |
69 } | |
70 | |
71 for (MessageContainer sink : findChildContainers()) { | |
72 if (visitedSinks.contains(sink)) { | |
73 continue; | |
74 } | |
75 | |
76 visitedSinks.add(sink); | |
77 if (sink.getMessageElement() == this.getMessageElement()) { | |
78 sink.emitMessagesImpl(context, baseElement, log, visitedSinks, childMessages); | |
79 } else { | |
80 sink.emitMessagesImpl(context, baseElement, log, visitedSinks, null); | |
81 } | |
82 } | |
83 } | |
84 | |
85 private List<Message> collectMessagesWithElementChildren(Set<MessageContainer> visitedSinks, Element e) { | |
86 if (visitedSinks.contains(this)) { | |
87 return Collections.emptyList(); | |
88 } | |
89 visitedSinks.add(this); | |
90 | |
91 List<Message> foundMessages = new ArrayList<>(); | |
92 if (Utils.typeEquals(getMessageElement().asType(), e.asType())) { | |
93 foundMessages.addAll(getMessages()); | |
94 } | |
95 for (MessageContainer sink : findChildContainers()) { | |
96 foundMessages.addAll(sink.collectMessagesWithElementChildren(visitedSinks, e)); | |
97 } | |
98 return foundMessages; | |
99 } | |
100 | |
101 private void verifyExpectedMessages(ProcessorContext context, Log log, List<Message> msgs) { | |
59 TypeElement expectError = context.getTruffleTypes().getExpectError(); | 102 TypeElement expectError = context.getTruffleTypes().getExpectError(); |
60 if (expectError != null) { | 103 if (expectError != null) { |
61 Element element = getMessageElement(); | 104 Element element = getMessageElement(); |
62 AnnotationMirror mirror = Utils.findAnnotationMirror(element.getAnnotationMirrors(), expectError); | 105 AnnotationMirror mirror = Utils.findAnnotationMirror(element.getAnnotationMirrors(), expectError); |
63 if (mirror != null) { | 106 if (mirror != null) { |
64 List<String> values = Utils.getAnnotationValueList(String.class, mirror, "value"); | 107 List<String> values = Utils.getAnnotationValueList(String.class, mirror, "value"); |
65 if (values == null) { | 108 if (values == null) { |
66 values = Collections.emptyList(); | 109 values = Collections.emptyList(); |
67 } | 110 } |
68 List<Message> msgs = getMessages(); | |
69 if (values.size() != msgs.size()) { | 111 if (values.size() != msgs.size()) { |
70 log.message(Kind.ERROR, element, mirror, Utils.getAnnotationValue(mirror, "value"), String.format("Error count expected %s but was %s.", values.size(), msgs.size())); | 112 log.message(Kind.ERROR, element, mirror, Utils.getAnnotationValue(mirror, "value"), String.format("Error count expected %s but was %s.", values.size(), msgs.size())); |
71 } | 113 } |
72 } | 114 } |
73 } | |
74 | |
75 for (Message message : getMessages()) { | |
76 emitDefault(context, baseElement, log, message); | |
77 } | |
78 | |
79 for (MessageContainer sink : findChildContainers()) { | |
80 if (visitedSinks.contains(sink)) { | |
81 continue; | |
82 } | |
83 | |
84 visitedSinks.add(sink); | |
85 sink.emitMessagesImpl(context, baseElement, log, visitedSinks); | |
86 } | 115 } |
87 } | 116 } |
88 | 117 |
89 private void emitDefault(ProcessorContext context, TypeElement baseType, Log log, Message message) { | 118 private void emitDefault(ProcessorContext context, TypeElement baseType, Log log, Message message) { |
90 Kind kind = message.getKind(); | 119 Kind kind = message.getKind(); |
97 } | 126 } |
98 | 127 |
99 String text = message.getText(); | 128 String text = message.getText(); |
100 | 129 |
101 TypeElement rootEnclosing = Utils.findRootEnclosingType(getMessageElement()); | 130 TypeElement rootEnclosing = Utils.findRootEnclosingType(getMessageElement()); |
102 if (rootEnclosing == null || !Utils.typeEquals(baseType.asType(), rootEnclosing.asType()) || this != message.getOriginalContainer()) { | 131 TypeElement baseEnclosing = Utils.findRootEnclosingType(baseType); |
132 if (rootEnclosing == null || !Utils.typeEquals(baseEnclosing.asType(), rootEnclosing.asType()) || this != message.getOriginalContainer()) { | |
103 // redirect message | 133 // redirect message |
104 MessageContainer original = message.getOriginalContainer(); | 134 MessageContainer original = message.getOriginalContainer(); |
105 messageElement = baseType; | 135 messageElement = baseType; |
106 messageAnnotation = null; | 136 messageAnnotation = null; |
107 messageValue = null; | 137 messageValue = null; |
111 TypeElement expectError = context.getTruffleTypes().getExpectError(); | 141 TypeElement expectError = context.getTruffleTypes().getExpectError(); |
112 if (expectError != null) { | 142 if (expectError != null) { |
113 AnnotationMirror mirror = Utils.findAnnotationMirror(messageElement.getAnnotationMirrors(), expectError); | 143 AnnotationMirror mirror = Utils.findAnnotationMirror(messageElement.getAnnotationMirrors(), expectError); |
114 if (mirror != null) { | 144 if (mirror != null) { |
115 List<String> expectedTexts = Utils.getAnnotationValueList(String.class, mirror, "value"); | 145 List<String> expectedTexts = Utils.getAnnotationValueList(String.class, mirror, "value"); |
116 if (!expectedTexts.contains(text)) { | 146 boolean found = false; |
117 log.message(kind, messageElement, mirror, Utils.getAnnotationValue(mirror, "value"), String.format("Message expected one of '%s' but was '%s'.", expectedTexts, text)); | 147 for (String expectedText : expectedTexts) { |
148 if (expectedText.endsWith("%") && text.startsWith(expectedText.substring(0, expectedText.length() - 1))) { | |
149 found = true; | |
150 break; | |
151 } else if (text.equals(expectedText)) { | |
152 found = true; | |
153 break; | |
154 } | |
155 } | |
156 if (!found) { | |
157 log.message(kind, messageElement, mirror, Utils.getAnnotationValue(mirror, "value"), "Message expected one of '%s' but was '%s'.", expectedTexts, text); | |
118 } else { | 158 } else { |
119 return; | 159 return; |
120 } | 160 } |
161 | |
121 } | 162 } |
122 } | 163 } |
123 | 164 |
124 log.message(kind, messageElement, messageAnnotation, messageValue, text); | 165 log.message(kind, messageElement, messageAnnotation, messageValue, text); |
125 } | 166 } |