OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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 file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /// Defines static information collected by the type checker and used later by | 5 /// Defines static information collected by the type checker and used later by |
6 /// emitters to generate code. | 6 /// emitters to generate code. |
7 library dev_compiler.src.info; | 7 library dev_compiler.src.info; |
8 | 8 |
9 import 'package:analyzer/src/generated/ast.dart'; | 9 import 'package:analyzer/src/generated/ast.dart'; |
10 import 'package:analyzer/src/generated/element.dart'; | 10 import 'package:analyzer/src/generated/element.dart'; |
11 import 'package:analyzer/src/generated/error.dart' | 11 import 'package:analyzer/src/generated/error.dart'; |
12 show AnalysisError, ErrorSeverity; | |
13 import 'package:logging/logging.dart' show Level; | |
14 | 12 |
15 import 'package:dev_compiler/src/checker/rules.dart'; | 13 import 'package:dev_compiler/src/checker/rules.dart'; |
16 import 'package:dev_compiler/src/utils.dart' as utils; | 14 import 'package:dev_compiler/src/utils.dart' as utils; |
17 | 15 |
18 import 'report.dart' show Message; | |
19 | |
20 /// Represents a summary of the results collected by running the program | 16 /// Represents a summary of the results collected by running the program |
21 /// checker. | 17 /// checker. |
22 class CheckerResults { | 18 class CheckerResults { |
23 final List<LibraryInfo> libraries; | 19 final List<LibraryInfo> libraries; |
24 final TypeRules rules; | 20 final TypeRules rules; |
25 final bool failure; | 21 final bool failure; |
26 | 22 |
27 CheckerResults(this.libraries, this.rules, this.failure); | 23 CheckerResults(this.libraries, this.rules, this.failure); |
28 } | 24 } |
29 | 25 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 Identity(DartType fromType) : super(fromType, fromType); | 80 Identity(DartType fromType) : super(fromType, fromType); |
85 } | 81 } |
86 | 82 |
87 // The error coercion. This coercion signals that a coercion | 83 // The error coercion. This coercion signals that a coercion |
88 // could not be generated. The code generator should not see | 84 // could not be generated. The code generator should not see |
89 // these. | 85 // these. |
90 class CoercionError extends Coercion { | 86 class CoercionError extends Coercion { |
91 CoercionError() : super(null, null); | 87 CoercionError() : super(null, null); |
92 } | 88 } |
93 | 89 |
94 abstract class StaticInfo implements Message { | 90 // TODO(jmesserly): this could use some refactoring. These are essentially |
| 91 // like ErrorCodes in analyzer, but we're including some details in our message. |
| 92 // Analyzer instead has template strings, and replaces '{0}' with the first |
| 93 // argument. |
| 94 abstract class StaticInfo { |
95 /// AST Node this info is attached to. | 95 /// AST Node this info is attached to. |
96 // TODO(jmesserly): this is somewhat redundant with SemanticNode. | |
97 AstNode get node; | 96 AstNode get node; |
98 | 97 |
99 @override | 98 // TODO(jmesserly): review the usage of error codes. We probably want our own, |
100 int get begin => node is AnnotatedNode | 99 // as well as some DDC specific [ErrorType]s. |
101 ? (node as AnnotatedNode).firstTokenAfterCommentAndMetadata.offset | 100 ErrorCode toErrorCode(); |
102 : node.offset; | |
103 | 101 |
104 @override | 102 // TODO(jmesserly): what convention to use here? |
105 int get end => node.end; | 103 String get name => 'dev_compiler.$runtimeType'; |
| 104 |
| 105 List<Object> get arguments => [node]; |
| 106 |
| 107 AnalysisError toAnalysisError() { |
| 108 int begin = node is AnnotatedNode |
| 109 ? (node as AnnotatedNode).firstTokenAfterCommentAndMetadata.offset |
| 110 : node.offset; |
| 111 int length = node.end - begin; |
| 112 var source = (node.root as CompilationUnit).element.source; |
| 113 return new AnalysisError(source, begin, length, toErrorCode(), arguments); |
| 114 } |
106 } | 115 } |
107 | 116 |
108 /// Implicitly injected expression conversion. | 117 /// Implicitly injected expression conversion. |
109 abstract class CoercionInfo extends StaticInfo { | 118 abstract class CoercionInfo extends StaticInfo { |
110 final TypeRules rules; | 119 final TypeRules rules; |
111 | 120 |
112 final Expression node; | 121 final Expression node; |
113 | 122 |
114 DartType get convertedType; | 123 DartType get convertedType; |
115 | 124 |
116 CoercionInfo(this.rules, this.node); | 125 CoercionInfo(this.rules, this.node); |
117 | 126 |
118 DartType get baseType => rules.getStaticType(node); | 127 DartType get baseType => rules.getStaticType(node); |
119 DartType get staticType => convertedType; | 128 DartType get staticType => convertedType; |
120 | 129 |
121 // safe iff this cannot throw | 130 String get message; |
122 bool get safe => false; | 131 toErrorCode() => new HintCode(name, message); |
123 | |
124 Level get level => safe ? Level.CONFIG : Level.INFO; | |
125 | |
126 String get description => '${this.runtimeType}: $baseType to $convertedType'; | |
127 | 132 |
128 static const String _propertyName = 'dev_compiler.src.info.CoercionInfo'; | 133 static const String _propertyName = 'dev_compiler.src.info.CoercionInfo'; |
129 | 134 |
130 /// Gets the coercion info associated with this node. | 135 /// Gets the coercion info associated with this node. |
131 static CoercionInfo get(AstNode node) => node.getProperty(_propertyName); | 136 static CoercionInfo get(AstNode node) => node.getProperty(_propertyName); |
132 | 137 |
133 /// Sets the coercion info associated with this node. | 138 /// Sets the coercion info associated with this node. |
134 static CoercionInfo set(AstNode node, CoercionInfo info) { | 139 static CoercionInfo set(AstNode node, CoercionInfo info) { |
135 node.setProperty(_propertyName, info); | 140 node.setProperty(_propertyName, info); |
136 return info; | 141 return info; |
(...skipping 11 matching lines...) Expand all Loading... |
148 (baseType.isDynamic || | 153 (baseType.isDynamic || |
149 // Call methods make the following non-redundant | 154 // Call methods make the following non-redundant |
150 _cast.toType.isSubtypeOf(baseType) || | 155 _cast.toType.isSubtypeOf(baseType) || |
151 baseType.isAssignableTo(_cast.toType))); | 156 baseType.isAssignableTo(_cast.toType))); |
152 } | 157 } |
153 | 158 |
154 Cast get cast => _cast; | 159 Cast get cast => _cast; |
155 | 160 |
156 DartType get convertedType => _cast.toType; | 161 DartType get convertedType => _cast.toType; |
157 | 162 |
158 String get message => '$node ($baseType) will need runtime check ' | 163 @override List<Object> get arguments => [node, baseType, convertedType]; |
159 'to cast to type $convertedType'; | 164 @override String get message => '{0} ({1}) will need runtime check ' |
| 165 'to cast to type {2}'; |
160 | 166 |
161 // Factory to create correct DownCast variant. | 167 // Factory to create correct DownCast variant. |
162 static StaticInfo create(TypeRules rules, Expression expression, Cast cast, | 168 static StaticInfo create(TypeRules rules, Expression expression, Cast cast, |
163 {String reason}) { | 169 {String reason}) { |
164 final fromT = cast.fromType; | 170 final fromT = cast.fromType; |
165 final toT = cast.toType; | 171 final toT = cast.toType; |
166 | 172 |
167 // toT <:_R fromT => to <: fromT | 173 // toT <:_R fromT => to <: fromT |
168 // NB: classes with call methods are subtypes of function | 174 // NB: classes with call methods are subtypes of function |
169 // types, but the function type is not assignable to the class | 175 // types, but the function type is not assignable to the class |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 | 230 |
225 // | 231 // |
226 // Standard down casts. These casts are implicitly injected by the compiler. | 232 // Standard down casts. These casts are implicitly injected by the compiler. |
227 // | 233 // |
228 | 234 |
229 // A down cast from dynamic to T. | 235 // A down cast from dynamic to T. |
230 class DynamicCast extends DownCast { | 236 class DynamicCast extends DownCast { |
231 DynamicCast(TypeRules rules, Expression expression, Cast cast) | 237 DynamicCast(TypeRules rules, Expression expression, Cast cast) |
232 : super._internal(rules, expression, cast); | 238 : super._internal(rules, expression, cast); |
233 | 239 |
234 final Level level = Level.INFO; | 240 toErrorCode() => new HintCode(name, message); |
235 } | 241 } |
236 | 242 |
237 // A down cast due to a variable declaration to a ground type. E.g., | 243 // A down cast due to a variable declaration to a ground type. E.g., |
238 // T x = expr; | 244 // T x = expr; |
239 // where T is ground. We exclude non-ground types as these behave differently | 245 // where T is ground. We exclude non-ground types as these behave differently |
240 // compared to standard Dart. | 246 // compared to standard Dart. |
241 class AssignmentCast extends DownCast { | 247 class AssignmentCast extends DownCast { |
242 AssignmentCast(TypeRules rules, Expression expression, Cast cast) | 248 AssignmentCast(TypeRules rules, Expression expression, Cast cast) |
243 : super._internal(rules, expression, cast); | 249 : super._internal(rules, expression, cast); |
244 | 250 |
245 final Level level = Level.INFO; | 251 toErrorCode() => new HintCode(name, message); |
246 } | 252 } |
247 | 253 |
248 // | 254 // |
249 // Temporary "casts" of allocation sites - literals, constructor invocations, | 255 // Temporary "casts" of allocation sites - literals, constructor invocations, |
250 // and closures. These should be handled by contextual inference. In most | 256 // and closures. These should be handled by contextual inference. In most |
251 // cases, inference will be sufficient, though in some it may unmask an actual | 257 // cases, inference will be sufficient, though in some it may unmask an actual |
252 // error: e.g., | 258 // error: e.g., |
253 // List<int> l = [1, 2, 3]; // Inference succeeds | 259 // List<int> l = [1, 2, 3]; // Inference succeeds |
254 // List<String> l = [1, 2, 3]; // Inference reveals static type error | 260 // List<String> l = [1, 2, 3]; // Inference reveals static type error |
255 // We're marking all as warnings for now. | 261 // We're marking all as warnings for now. |
256 // | 262 // |
257 // TODO(vsm,leafp): Remove this. | 263 // TODO(vsm,leafp): Remove this. |
258 class UninferredClosure extends DownCast { | 264 class UninferredClosure extends DownCast { |
259 UninferredClosure(TypeRules rules, FunctionExpression expression, Cast cast) | 265 UninferredClosure(TypeRules rules, FunctionExpression expression, Cast cast) |
260 : super._internal(rules, expression, cast); | 266 : super._internal(rules, expression, cast); |
261 | 267 |
262 final Level level = Level.WARNING; | 268 toErrorCode() => new StaticTypeWarningCode(name, message); |
263 } | 269 } |
264 | 270 |
265 // | 271 // |
266 // Implicit down casts. These are only injected by the compiler by flag. | 272 // Implicit down casts. These are only injected by the compiler by flag. |
267 // | 273 // |
268 | 274 |
269 // A down cast to a non-ground type. These behave differently from standard | 275 // A down cast to a non-ground type. These behave differently from standard |
270 // Dart and may be more likely to fail at runtime. | 276 // Dart and may be more likely to fail at runtime. |
271 class DownCastComposite extends DownCast { | 277 class DownCastComposite extends DownCast { |
272 DownCastComposite(TypeRules rules, Expression expression, Cast cast) | 278 DownCastComposite(TypeRules rules, Expression expression, Cast cast) |
273 : super._internal(rules, expression, cast); | 279 : super._internal(rules, expression, cast); |
274 | 280 |
275 final Level level = Level.WARNING; | 281 toErrorCode() => new StaticTypeWarningCode(name, message); |
276 } | 282 } |
277 | 283 |
278 // A down cast to a non-ground type. These behave differently from standard | 284 // A down cast to a non-ground type. These behave differently from standard |
279 // Dart and may be more likely to fail at runtime. | 285 // Dart and may be more likely to fail at runtime. |
280 class DownCastImplicit extends DownCast { | 286 class DownCastImplicit extends DownCast { |
281 DownCastImplicit(TypeRules rules, Expression expression, Cast cast) | 287 DownCastImplicit(TypeRules rules, Expression expression, Cast cast) |
282 : super._internal(rules, expression, cast); | 288 : super._internal(rules, expression, cast); |
283 | 289 |
284 final Level level = Level.WARNING; | 290 toErrorCode() => new StaticTypeWarningCode(name, message); |
285 } | 291 } |
286 | 292 |
287 // An inferred type for the wrapped expression, which may need to be | 293 // An inferred type for the wrapped expression, which may need to be |
288 // reified into the term | 294 // reified into the term |
289 abstract class InferredTypeBase extends CoercionInfo { | 295 abstract class InferredTypeBase extends CoercionInfo { |
290 final DartType _type; | 296 final DartType _type; |
291 | 297 |
292 InferredTypeBase._internal(TypeRules rules, Expression expression, this._type) | 298 InferredTypeBase._internal(TypeRules rules, Expression expression, this._type) |
293 : super(rules, expression); | 299 : super(rules, expression); |
294 | 300 |
295 DartType get type => _type; | 301 DartType get type => _type; |
296 DartType get convertedType => type; | 302 DartType get convertedType => type; |
297 String get message => '$node has inferred type $type'; | 303 @override String get message => '{0} has inferred type {1}'; |
298 Level get level => Level.INFO; | 304 @override List get arguments => [node, type]; |
| 305 |
| 306 toErrorCode() => new HintCode(name, message); |
299 } | 307 } |
300 | 308 |
301 // Standard / unspecialized inferred type | 309 // Standard / unspecialized inferred type |
302 class InferredType extends InferredTypeBase { | 310 class InferredType extends InferredTypeBase { |
303 InferredType(TypeRules rules, Expression expression, DartType type) | 311 InferredType(TypeRules rules, Expression expression, DartType type) |
304 : super._internal(rules, expression, type); | 312 : super._internal(rules, expression, type); |
305 | 313 |
306 // Factory to create correct InferredType variant. | 314 // Factory to create correct InferredType variant. |
307 static InferredTypeBase create( | 315 static InferredTypeBase create( |
308 TypeRules rules, Expression expression, DartType type) { | 316 TypeRules rules, Expression expression, DartType type) { |
(...skipping 28 matching lines...) Expand all Loading... |
337 class InferredTypeClosure extends InferredTypeBase { | 345 class InferredTypeClosure extends InferredTypeBase { |
338 InferredTypeClosure(TypeRules rules, Expression expression, DartType type) | 346 InferredTypeClosure(TypeRules rules, Expression expression, DartType type) |
339 : super._internal(rules, expression, type); | 347 : super._internal(rules, expression, type); |
340 } | 348 } |
341 | 349 |
342 class DynamicInvoke extends CoercionInfo { | 350 class DynamicInvoke extends CoercionInfo { |
343 DynamicInvoke(TypeRules rules, Expression expression) | 351 DynamicInvoke(TypeRules rules, Expression expression) |
344 : super(rules, expression); | 352 : super(rules, expression); |
345 | 353 |
346 DartType get convertedType => rules.provider.dynamicType; | 354 DartType get convertedType => rules.provider.dynamicType; |
347 String get message => '$node requires dynamic invoke'; | 355 String get message => '{0} requires dynamic invoke'; |
348 Level get level => Level.INFO; | 356 toErrorCode() => new HintCode(name, message); |
349 | 357 |
350 static const String _propertyName = 'dev_compiler.src.info.DynamicInvoke'; | 358 static const String _propertyName = 'dev_compiler.src.info.DynamicInvoke'; |
351 | 359 |
352 /// Whether this [node] is the target of a dynamic operation. | 360 /// Whether this [node] is the target of a dynamic operation. |
353 static bool get(AstNode node) { | 361 static bool get(AstNode node) { |
354 var value = node.getProperty(_propertyName); | 362 var value = node.getProperty(_propertyName); |
355 return value != null ? value : false; | 363 return value != null ? value : false; |
356 } | 364 } |
357 | 365 |
358 /// Sets whether this node is the target of a dynamic operation. | 366 /// Sets whether this node is the target of a dynamic operation. |
359 static bool set(AstNode node, bool value) { | 367 static bool set(AstNode node, bool value) { |
360 // Free the storage for things that aren't dynamic. | 368 // Free the storage for things that aren't dynamic. |
361 if (value == false) value = null; | 369 if (value == false) value = null; |
362 node.setProperty(_propertyName, value); | 370 node.setProperty(_propertyName, value); |
363 return value; | 371 return value; |
364 } | 372 } |
365 } | 373 } |
366 | 374 |
367 abstract class StaticError extends StaticInfo { | 375 abstract class StaticError extends StaticInfo { |
368 final AstNode node; | 376 final AstNode node; |
369 | 377 |
370 StaticError(this.node); | 378 StaticError(this.node); |
371 | 379 |
372 Level get level => Level.SEVERE; | 380 String get message; |
| 381 |
| 382 toErrorCode() => new CompileTimeErrorCode(name, message); |
373 } | 383 } |
374 | 384 |
375 class StaticTypeError extends StaticError { | 385 class StaticTypeError extends StaticError { |
376 final DartType baseType; | 386 final DartType baseType; |
377 final DartType expectedType; | 387 final DartType expectedType; |
378 String reason = null; | 388 String reason = null; |
379 | 389 |
380 StaticTypeError(TypeRules rules, Expression expression, this.expectedType, | 390 StaticTypeError(TypeRules rules, Expression expression, this.expectedType, |
381 {this.reason}) | 391 {this.reason}) |
382 : baseType = rules.getStaticType(expression), | 392 : baseType = rules.getStaticType(expression), |
383 super(expression); | 393 super(expression); |
384 | 394 |
385 String get message => | 395 @override List<Object> get arguments => [node, baseType, expectedType]; |
386 'Type check failed: $node ($baseType) is not of type $expectedType' + | 396 @override String get message => |
| 397 'Type check failed: {0} ({1}) is not of type {2}' + |
387 ((reason == null) ? '' : ' because $reason'); | 398 ((reason == null) ? '' : ' because $reason'); |
388 } | 399 } |
389 | 400 |
390 class InvalidVariableDeclaration extends StaticError { | 401 class InvalidVariableDeclaration extends StaticError { |
391 final DartType expectedType; | 402 final DartType expectedType; |
392 | 403 |
393 InvalidVariableDeclaration( | 404 InvalidVariableDeclaration( |
394 TypeRules rules, AstNode declaration, this.expectedType) | 405 TypeRules rules, AstNode declaration, this.expectedType) |
395 : super(declaration); | 406 : super(declaration); |
396 | 407 |
397 String get message => 'Type check failed: null is not of type $expectedType'; | 408 @override List<Object> get arguments => [expectedType]; |
| 409 @override String get message => 'Type check failed: null is not of type {0}'; |
398 } | 410 } |
399 | 411 |
400 class InvalidParameterDeclaration extends StaticError { | 412 class InvalidParameterDeclaration extends StaticError { |
401 final DartType expectedType; | 413 final DartType expectedType; |
402 | 414 |
403 InvalidParameterDeclaration( | 415 InvalidParameterDeclaration( |
404 TypeRules rules, FormalParameter declaration, this.expectedType) | 416 TypeRules rules, FormalParameter declaration, this.expectedType) |
405 : super(declaration); | 417 : super(declaration); |
406 | 418 |
407 String get message => 'Type check failed: $node is not of type $expectedType'; | 419 @override List<Object> get arguments => [node, expectedType]; |
| 420 @override String get message => 'Type check failed: {0} is not of type {1}'; |
408 } | 421 } |
409 | 422 |
410 class InvalidRuntimeCheckError extends StaticError { | 423 class InvalidRuntimeCheckError extends StaticError { |
411 final DartType type; | 424 final DartType type; |
412 | 425 |
413 InvalidRuntimeCheckError(AstNode node, this.type) : super(node) { | 426 InvalidRuntimeCheckError(AstNode node, this.type) : super(node) { |
414 assert(node is IsExpression || node is AsExpression); | 427 assert(node is IsExpression || node is AsExpression); |
415 } | 428 } |
416 | 429 |
417 String get message => "Invalid runtime check on non-ground type $type"; | 430 @override List<Object> get arguments => [type]; |
| 431 String get message => "Invalid runtime check on non-ground type {0}"; |
418 } | 432 } |
419 | 433 |
420 // Invalid override of an instance member of a class. | 434 // Invalid override of an instance member of a class. |
421 abstract class InvalidOverride extends StaticError { | 435 abstract class InvalidOverride extends StaticError { |
422 /// Member delaration with the invalid override. | 436 /// Member declaration with the invalid override. |
423 final ExecutableElement element; | 437 final ExecutableElement element; |
424 | 438 |
425 /// Type (class or interface) that provides the base declaration. | 439 /// Type (class or interface) that provides the base declaration. |
426 final InterfaceType base; | 440 final InterfaceType base; |
427 | 441 |
428 /// Actual type of the overridden member. | 442 /// Actual type of the overridden member. |
429 final DartType subType; | 443 final DartType subType; |
430 | 444 |
431 /// Actual type of the base member. | 445 /// Actual type of the base member. |
432 final DartType baseType; | 446 final DartType baseType; |
433 | 447 |
434 /// Whether the error comes from combining a base class and an interface | 448 /// Whether the error comes from combining a base class and an interface |
435 final bool fromBaseClass; | 449 final bool fromBaseClass; |
436 | 450 |
437 /// Whether the error comes from a mixin (either overriding a base class or an | 451 /// Whether the error comes from a mixin (either overriding a base class or an |
438 /// interface declaration). | 452 /// interface declaration). |
439 final bool fromMixin; | 453 final bool fromMixin; |
440 | 454 |
441 InvalidOverride( | 455 InvalidOverride( |
442 AstNode node, this.element, this.base, this.subType, this.baseType) | 456 AstNode node, this.element, this.base, this.subType, this.baseType) |
443 : fromBaseClass = node is ExtendsClause, | 457 : fromBaseClass = node is ExtendsClause, |
444 fromMixin = node.parent is WithClause, | 458 fromMixin = node.parent is WithClause, |
445 super(node); | 459 super(node); |
446 | 460 |
447 ClassElement get parent => element.enclosingElement; | 461 ClassElement get parent => element.enclosingElement; |
448 | 462 |
| 463 @override List<Object> get arguments => [parent.name, element.name, subType, b
ase, baseType]; |
| 464 |
449 String _messageHelper(String errorName) { | 465 String _messageHelper(String errorName) { |
450 var name = element.name; | |
451 var lcErrorName = errorName.toLowerCase(); | 466 var lcErrorName = errorName.toLowerCase(); |
452 var intro = fromBaseClass | 467 var intro = fromBaseClass |
453 ? 'Base class introduces an $lcErrorName' | 468 ? 'Base class introduces an $lcErrorName' |
454 : (fromMixin ? 'Mixin introduces an $lcErrorName' : errorName); | 469 : (fromMixin ? 'Mixin introduces an $lcErrorName' : errorName); |
455 return '$intro. The type of ${parent.name}.$name ($subType) is not a ' | 470 return '$intro. The type of {0}.{1} ({2}) is not a ' |
456 'subtype of $base.$name ($baseType).'; | 471 'subtype of {3}.{1} ({4}).'; |
457 } | 472 } |
458 } | 473 } |
459 | 474 |
460 // Invalid override due to incompatible type. I.e., the overridden signature | 475 // Invalid override due to incompatible type. I.e., the overridden signature |
461 // is not compatible with the original. | 476 // is not compatible with the original. |
462 class InvalidMethodOverride extends InvalidOverride { | 477 class InvalidMethodOverride extends InvalidOverride { |
463 InvalidMethodOverride(AstNode node, ExecutableElement element, | 478 InvalidMethodOverride(AstNode node, ExecutableElement element, |
464 InterfaceType base, FunctionType subType, FunctionType baseType) | 479 InterfaceType base, FunctionType subType, FunctionType baseType) |
465 : super(node, element, base, subType, baseType); | 480 : super(node, element, base, subType, baseType); |
466 | 481 |
467 String get message => _messageHelper('Invalid override'); | 482 String get message => _messageHelper('Invalid override'); |
468 } | 483 } |
469 | 484 |
470 // TODO(sigmund): delete, if we fix this, this should be part of the type | 485 // TODO(sigmund): delete, if we fix this, this should be part of the type |
471 // inference, not something we detect in the checker. | 486 // inference, not something we detect in the checker. |
472 // TODO(sigmund): split and track field, getter, setter, method separately | 487 // TODO(sigmund): split and track field, getter, setter, method separately |
473 class InferableOverride extends InvalidOverride { | 488 class InferableOverride extends InvalidOverride { |
474 InferableOverride(AstNode node, ExecutableElement element, InterfaceType base, | 489 InferableOverride(AstNode node, ExecutableElement element, InterfaceType base, |
475 DartType subType, DartType baseType) | 490 DartType subType, DartType baseType) |
476 : super(node, element, base, subType, baseType); | 491 : super(node, element, base, subType, baseType); |
477 | 492 |
478 Level get level => Level.SEVERE; | 493 toErrorCode() => new CompileTimeErrorCode(name, message); |
479 String get message => _messageHelper('Invalid but inferable override'); | 494 String get message => _messageHelper('Invalid but inferable override'); |
480 } | 495 } |
481 | 496 |
482 /// Used to mark unexpected situations in our compiler were we couldn't compute | 497 /// Used to mark unexpected situations in our compiler were we couldn't compute |
483 /// the type of an expression. | 498 /// the type of an expression. |
484 // TODO(sigmund): This is normally a result of another error that is caught by | 499 // TODO(sigmund): This is normally a result of another error that is caught by |
485 // the analyzer, so this should likely be removed in the future. | 500 // the analyzer, so this should likely be removed in the future. |
486 class MissingTypeError extends StaticInfo { | 501 class MissingTypeError extends StaticInfo { |
487 final AstNode node; | 502 final AstNode node; |
488 Level get level => Level.WARNING; | 503 toErrorCode() => new StaticTypeWarningCode(name, message); |
489 | 504 |
| 505 MissingTypeError(this.node); |
| 506 |
| 507 @override List<Object> get arguments => [node, node.runtimeType]; |
490 String get message => | 508 String get message => |
491 "type analysis didn't compute the type of: $node ${node.runtimeType}"; | 509 "type analysis didn't compute the type of: {0} {1}"; |
492 MissingTypeError(this.node); | |
493 } | 510 } |
494 | 511 |
495 /// Dart constructors have one weird quirk, illustrated with this example: | 512 /// Dart constructors have one weird quirk, illustrated with this example: |
496 /// | 513 /// |
497 /// class Base { | 514 /// class Base { |
498 /// var x; | 515 /// var x; |
499 /// Base() : x = print('Base.1') { | 516 /// Base() : x = print('Base.1') { |
500 /// print('Base.2'); | 517 /// print('Base.2'); |
501 /// } | 518 /// } |
502 /// } | 519 /// } |
(...skipping 14 matching lines...) Expand all Loading... |
517 /// immediately after super initializers. Normally this isn't observable, but it | 534 /// immediately after super initializers. Normally this isn't observable, but it |
518 /// could be if initializers have side effects. | 535 /// could be if initializers have side effects. |
519 /// | 536 /// |
520 /// Better to have `super` at the end, as required by the Dart style guide: | 537 /// Better to have `super` at the end, as required by the Dart style guide: |
521 /// <http://goo.gl/q1T4BB> | 538 /// <http://goo.gl/q1T4BB> |
522 /// | 539 /// |
523 /// For now this is the only pattern we support. | 540 /// For now this is the only pattern we support. |
524 class InvalidSuperInvocation extends StaticError { | 541 class InvalidSuperInvocation extends StaticError { |
525 InvalidSuperInvocation(SuperConstructorInvocation node) : super(node); | 542 InvalidSuperInvocation(SuperConstructorInvocation node) : super(node); |
526 | 543 |
527 String get message => "super call must be last in an initializer list " | 544 @override String get message => "super call must be last in an initializer " |
528 "(see http://goo.gl/q1T4BB): $node"; | 545 "list (see http://goo.gl/q1T4BB): {0}"; |
529 } | 546 } |
530 | |
531 class AnalyzerMessage extends Message { | |
532 factory AnalyzerMessage.from(AnalysisError error) { | |
533 var severity = error.errorCode.type.severity; | |
534 var isError = severity == ErrorSeverity.WARNING; | |
535 var level = isError ? Level.SEVERE : Level.WARNING; | |
536 int begin = error.offset; | |
537 int end = begin + error.length; | |
538 return new AnalyzerMessage(error.message, level, begin, end); | |
539 } | |
540 | |
541 const AnalyzerMessage(String message, Level level, int begin, int end) | |
542 : super(message, level, begin, end); | |
543 } | |
OLD | NEW |