Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Side by Side Diff: pkg/fletchc/lib/src/diagnostic.dart

Issue 1659163007: Rename fletch -> dartino (Closed) Base URL: https://github.com/dartino/sdk.git@master
Patch Set: address comments Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/fletchc/lib/src/device_type.dart ('k') | pkg/fletchc/lib/src/dynamic_call_enqueuer.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE.md file.
4
5 library fletchc.diagnostic;
6
7 import 'messages.dart' show
8 DiagnosticKind,
9 getMessage;
10
11 import 'hub/sentence_parser.dart' show
12 Preposition,
13 Target,
14 TargetKind,
15 Verb;
16
17 export 'messages.dart' show
18 DiagnosticKind;
19
20 /// Represents a parameter to a diagnostic, that is, a key in the `arguments`
21 /// map of [Diagnostic]. In a diagnostic message template (a [String]), a
22 /// parameter is represented by `"#{name}"`.
23 class DiagnosticParameter {
24 final DiagnosticParameterType type;
25
26 final String name;
27
28 const DiagnosticParameter(this.type, this.name);
29
30 String toString() => '#{$name}';
31
32 static const DiagnosticParameter message = const DiagnosticParameter(
33 DiagnosticParameterType.string, 'message');
34
35 static const DiagnosticParameter verb = const DiagnosticParameter(
36 DiagnosticParameterType.verb, 'verb');
37
38 static const DiagnosticParameter sessionName = const DiagnosticParameter(
39 DiagnosticParameterType.sessionName, 'sessionName');
40
41 static const DiagnosticParameter target = const DiagnosticParameter(
42 DiagnosticParameterType.target, 'target');
43
44 static const DiagnosticParameter requiredTarget = const DiagnosticParameter(
45 DiagnosticParameterType.targetKind, 'requiredTarget');
46
47 static const DiagnosticParameter userInput = const DiagnosticParameter(
48 DiagnosticParameterType.string, 'userInput');
49
50 static const DiagnosticParameter additionalUserInput =
51 const DiagnosticParameter(
52 DiagnosticParameterType.string, 'additionalUserInput');
53
54 static const DiagnosticParameter address = const DiagnosticParameter(
55 DiagnosticParameterType.string, 'address');
56
57 static const DiagnosticParameter preposition = const DiagnosticParameter(
58 DiagnosticParameterType.preposition, 'preposition');
59
60 // TODO(ahe): This should probably be a more generalized location, for
61 // example, Spannable from dart2js.
62 static const DiagnosticParameter uri = const DiagnosticParameter(
63 DiagnosticParameterType.uri, 'uri');
64
65 static const DiagnosticParameter fixit = const DiagnosticParameter(
66 DiagnosticParameterType.string, 'fixit');
67 }
68
69 enum DiagnosticParameterType {
70 string,
71 verb,
72 sessionName,
73 target,
74 targetKind,
75 preposition,
76 uri,
77 }
78
79 class Diagnostic {
80 final DiagnosticKind kind;
81
82 final String template;
83
84 final Map<DiagnosticParameter, dynamic> arguments;
85
86 const Diagnostic(this.kind, this.template, this.arguments);
87
88 String toString() => 'Diagnostic($kind, $template, $arguments)';
89
90 /// Convert [template] to a human-readable message. This entails replacing
91 /// all occurences of `"#{parameterName}"` with the corresponding value in
92 /// [arguments].
93 String formatMessage() {
94 String formattedMessage = template;
95 Set<String> suppliedParameters = new Set<String>();
96 arguments.forEach((DiagnosticParameter parameter, value) {
97 suppliedParameters.add('$parameter');
98 String stringValue;
99 switch (parameter.type) {
100 case DiagnosticParameterType.string:
101 stringValue = value;
102 break;
103
104 case DiagnosticParameterType.uri:
105 stringValue = '$value';
106 break;
107
108 case DiagnosticParameterType.verb:
109 Verb verb = value;
110 stringValue = verb.name;
111 break;
112
113 case DiagnosticParameterType.sessionName:
114 stringValue = value;
115 break;
116
117 case DiagnosticParameterType.target:
118 Target target = value;
119 // TODO(karlklose): Improve this conversion.
120 stringValue = '$target';
121 break;
122
123 case DiagnosticParameterType.targetKind:
124 TargetKind kind = value;
125 // TODO(karlklose): Improve this conversion.
126 stringValue = '$kind';
127 break;
128
129 case DiagnosticParameterType.preposition:
130 Preposition preposition = value;
131 // TODO(karlklose): Improve this conversion.
132 stringValue =
133 preposition.kind.toString().split('.').last.toLowerCase();
134 break;
135
136 default:
137 throwInternalError("""
138 Unsupported parameter type '${parameter.type}'
139 found for parameter '$parameter'
140 when trying to format the following error message:
141
142 $formattedMessage""");
143 break;
144 }
145 formattedMessage = formattedMessage.replaceAll('$parameter', stringValue);
146 });
147
148 Set<String> usedParameters = new Set<String>();
149 for (Match match in new RegExp("#{[^}]*}").allMatches(template)) {
150 String parameter = match.group(0);
151 usedParameters.add(parameter);
152 }
153
154 Set<String> unusedParameters =
155 suppliedParameters.difference(usedParameters);
156 Set<String> missingParameters =
157 usedParameters.difference(suppliedParameters);
158
159 if (missingParameters.isNotEmpty || unusedParameters.isNotEmpty) {
160 throw """
161 Error when formatting diagnostic:
162 kind: $kind
163 template: $template
164 arguments: $arguments
165 missingParameters: ${missingParameters.join(', ')}
166 unusedParameters: ${unusedParameters.join(', ')}
167 formattedMessage: $formattedMessage""";
168 }
169
170 return formattedMessage;
171 }
172 }
173
174 class InputError {
175 final DiagnosticKind kind;
176
177 final Map<DiagnosticParameter, dynamic> arguments;
178
179 const InputError(this.kind, [this.arguments]);
180
181 Diagnostic asDiagnostic() {
182 return new Diagnostic(kind, getMessage(kind), arguments);
183 }
184
185 String toString() => 'InputError($kind, $arguments)';
186 }
187
188 /// Throw an internal error that will be recorded as a compiler crash.
189 ///
190 /// In general, assume, no matter how unlikely, that [message] may be read by a
191 /// user (that is, a developer using Fletch). For this reason, try to:
192 ///
193 /// * Avoid phrases that can be interpreted as blaming the user (all error
194 /// messages should state what is wrong, in a way that doesn't assign blame).
195 ///
196 /// * Avoid being cute or funny (there's nothing more frustrating than being
197 /// affected by a bug and see a cute or funny message, especially if it
198 /// happens a lot).
199 ///
200 /// * Avoid phrases like "unreachable", "can't happen", "shouldn't happen",
201 /// "shouldn't be called", simply because it is wrong: it did happen. In most
202 /// cases a factual message would be "unimplemented", "unhandled case",
203 /// etc. Remember that the stacktrace will pinpoint the exact location of the
204 /// problem, so no need to repeat a method name.
205 void throwInternalError(String message) {
206 throw new InputError(
207 DiagnosticKind.internalError,
208 <DiagnosticParameter, dynamic>{DiagnosticParameter.message: message});
209 }
210
211 void throwFatalError(
212 DiagnosticKind kind,
213 {String message,
214 Verb verb,
215 String sessionName,
216 Target target,
217 TargetKind requiredTarget,
218 String address,
219 String userInput,
220 String additionalUserInput,
221 Preposition preposition,
222 Uri uri,
223 String fixit}) {
224 Map<DiagnosticParameter, dynamic> arguments =
225 <DiagnosticParameter, dynamic>{};
226 if (message != null) {
227 arguments[DiagnosticParameter.message] = message;
228 }
229 if (verb != null) {
230 arguments[DiagnosticParameter.verb] = verb;
231 }
232 if (sessionName != null) {
233 arguments[DiagnosticParameter.sessionName] = sessionName;
234 }
235 if (target != null) {
236 arguments[DiagnosticParameter.target] = target;
237 }
238 if (address != null) {
239 arguments[DiagnosticParameter.address] = address;
240 }
241 if (userInput != null) {
242 arguments[DiagnosticParameter.userInput] = userInput;
243 }
244 if (additionalUserInput != null) {
245 arguments[DiagnosticParameter.additionalUserInput] = additionalUserInput;
246 }
247 if (preposition != null) {
248 arguments[DiagnosticParameter.preposition] = preposition;
249 }
250 if (uri != null) {
251 arguments[DiagnosticParameter.uri] = uri;
252 }
253 if (requiredTarget != null) {
254 arguments[DiagnosticParameter.requiredTarget] = requiredTarget;
255 }
256 if (fixit != null) {
257 arguments[DiagnosticParameter.fixit] = fixit;
258 }
259 throw new InputError(kind, arguments);
260 }
OLDNEW
« no previous file with comments | « pkg/fletchc/lib/src/device_type.dart ('k') | pkg/fletchc/lib/src/dynamic_call_enqueuer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698