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

Side by Side Diff: pkg/analyzer/lib/src/task/strong/info.dart

Issue 1497253002: Align strong-mode error codes with analyzer conv. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: doc_fixes Created 5 years 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 | « no previous file | pkg/analyzer/test/src/task/dart_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be 7 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be
8 // refactored to fit into analyzer. 8 // refactored to fit into analyzer.
9 library analyzer.src.task.strong.info; 9 library analyzer.src.task.strong.info;
10 10
11 import 'package:analyzer/src/generated/ast.dart'; 11 import 'package:analyzer/src/generated/ast.dart';
12 import 'package:analyzer/src/generated/element.dart'; 12 import 'package:analyzer/src/generated/element.dart';
13 import 'package:analyzer/src/generated/error.dart'; 13 import 'package:analyzer/src/generated/error.dart';
14 14
15 import 'rules.dart'; 15 import 'rules.dart';
16 16
17 // The abstract type of coercions mapping one type to another. 17 // The abstract type of coercions mapping one type to another.
Leaf 2015/12/04 19:32:15 I think this comment got duped from below?
pquitslund 2015/12/04 23:34:22 Done.
18 // This class also exposes static builder functions which 18 // This class also exposes static builder functions which
19 // check for errors and reduce redundant coercions to the identity. 19 // check for errors and reduce redundant coercions to the identity.
20 abstract class Coercion { 20 class AssignmentCast extends DownCast {
21 final DartType fromType; 21 AssignmentCast(TypeRules rules, Expression expression, Cast cast)
22 final DartType toType; 22 : super._internal(rules, expression, cast);
23 Coercion(this.fromType, this.toType); 23
24 static Coercion cast(DartType fromT, DartType toT) => new Cast(fromT, toT); 24 @override
25 static Coercion identity(DartType type) => new Identity(type); 25 String get name => 'STRONG_MODE_ASSIGNMENT_CAST';
26 static Coercion error() => new CoercionError(); 26
27 toErrorCode() => new HintCode(name, message);
27 } 28 }
28 29
29 // Coercion which casts one type to another 30 // Coercion which casts one type to another
30 class Cast extends Coercion { 31 class Cast extends Coercion {
31 Cast(DartType fromType, DartType toType) : super(fromType, toType); 32 Cast(DartType fromType, DartType toType) : super(fromType, toType);
32 } 33 }
33 34
34 // The identity coercion 35 // The abstract type of coercions mapping one type to another.
35 class Identity extends Coercion { 36 // This class also exposes static builder functions which
36 Identity(DartType fromType) : super(fromType, fromType); 37 // check for errors and reduce redundant coercions to the identity.
38 abstract class Coercion {
39 final DartType fromType;
40 final DartType toType;
41 Coercion(this.fromType, this.toType);
42 static Coercion cast(DartType fromT, DartType toT) => new Cast(fromT, toT);
43 static Coercion error() => new CoercionError();
44 static Coercion identity(DartType type) => new Identity(type);
37 } 45 }
38 46
39 // The error coercion. This coercion signals that a coercion 47 // The error coercion. This coercion signals that a coercion
40 // could not be generated. The code generator should not see 48 // could not be generated. The code generator should not see
41 // these. 49 // these.
42 class CoercionError extends Coercion { 50 class CoercionError extends Coercion {
43 CoercionError() : super(null, null); 51 CoercionError() : super(null, null);
44 } 52 }
45 53
46 // TODO(jmesserly): this could use some refactoring. These are essentially
47 // like ErrorCodes in analyzer, but we're including some details in our message.
48 // Analyzer instead has template strings, and replaces '{0}' with the first
49 // argument.
50 abstract class StaticInfo {
51 /// AST Node this info is attached to.
52 AstNode get node;
53
54 // TODO(jmesserly): review the usage of error codes. We probably want our own,
55 // as well as some DDC specific [ErrorType]s.
56 ErrorCode toErrorCode();
57
58 // TODO(jmesserly): what convention to use here?
59 String get name => 'dev_compiler.$runtimeType';
60
61 List<Object> get arguments => [node];
62
63 AnalysisError toAnalysisError() {
64 int begin = node is AnnotatedNode
65 ? (node as AnnotatedNode).firstTokenAfterCommentAndMetadata.offset
66 : node.offset;
67 int length = node.end - begin;
68 var source = (node.root as CompilationUnit).element.source;
69 return new AnalysisError(source, begin, length, toErrorCode(), arguments);
70 }
71 }
72
73 /// Implicitly injected expression conversion. 54 /// Implicitly injected expression conversion.
74 abstract class CoercionInfo extends StaticInfo { 55 abstract class CoercionInfo extends StaticInfo {
56 static const String _propertyName = 'dev_compiler.src.info.CoercionInfo';
57
75 final TypeRules rules; 58 final TypeRules rules;
76 59
77 final Expression node; 60 final Expression node;
78 61
79 DartType get convertedType;
80
81 CoercionInfo(this.rules, this.node); 62 CoercionInfo(this.rules, this.node);
82 63
83 DartType get baseType => rules.getStaticType(node); 64 DartType get baseType => rules.getStaticType(node);
65 DartType get convertedType;
66
67 String get message;
84 DartType get staticType => convertedType; 68 DartType get staticType => convertedType;
85 69
86 String get message;
87 toErrorCode() => new HintCode(name, message); 70 toErrorCode() => new HintCode(name, message);
88 71
89 static const String _propertyName = 'dev_compiler.src.info.CoercionInfo';
90
91 /// Gets the coercion info associated with this node. 72 /// Gets the coercion info associated with this node.
92 static CoercionInfo get(AstNode node) => node.getProperty(_propertyName); 73 static CoercionInfo get(AstNode node) => node.getProperty(_propertyName);
93 74
94 /// Sets the coercion info associated with this node. 75 /// Sets the coercion info associated with this node.
95 static CoercionInfo set(AstNode node, CoercionInfo info) { 76 static CoercionInfo set(AstNode node, CoercionInfo info) {
96 node.setProperty(_propertyName, info); 77 node.setProperty(_propertyName, info);
97 return info; 78 return info;
98 } 79 }
99 } 80 }
100 81
101 // Base class for all casts from base type to sub type. 82 // Base class for all casts from base type to sub type.
102 abstract class DownCast extends CoercionInfo { 83 abstract class DownCast extends CoercionInfo {
103 Cast _cast; 84 Cast _cast;
104 85
105 DownCast._internal(TypeRules rules, Expression expression, this._cast) 86 DownCast._internal(TypeRules rules, Expression expression, this._cast)
106 : super(rules, expression) { 87 : super(rules, expression) {
107 assert(_cast.toType != baseType && 88 assert(_cast.toType != baseType &&
108 _cast.fromType == baseType && 89 _cast.fromType == baseType &&
109 (baseType.isDynamic || 90 (baseType.isDynamic ||
110 // Call methods make the following non-redundant 91 // Call methods make the following non-redundant
111 _cast.toType.isSubtypeOf(baseType) || 92 _cast.toType.isSubtypeOf(baseType) ||
112 baseType.isAssignableTo(_cast.toType))); 93 baseType.isAssignableTo(_cast.toType)));
113 } 94 }
114 95
96 @override List<Object> get arguments => [node, baseType, convertedType];
97
115 Cast get cast => _cast; 98 Cast get cast => _cast;
116 99
117 DartType get convertedType => _cast.toType; 100 DartType get convertedType => _cast.toType;
118
119 @override List<Object> get arguments => [node, baseType, convertedType];
120 @override String get message => '{0} ({1}) will need runtime check ' 101 @override String get message => '{0} ({1}) will need runtime check '
121 'to cast to type {2}'; 102 'to cast to type {2}';
122 103
123 // Factory to create correct DownCast variant. 104 // Factory to create correct DownCast variant.
124 static StaticInfo create(TypeRules rules, Expression expression, Cast cast, 105 static StaticInfo create(TypeRules rules, Expression expression, Cast cast,
125 {String reason}) { 106 {String reason}) {
126 final fromT = cast.fromType; 107 final fromT = cast.fromType;
127 final toT = cast.toType; 108 final toT = cast.toType;
128 109
129 // toT <:_R fromT => to <: fromT 110 // toT <:_R fromT => to <: fromT
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 if (parent is VariableDeclaration && (parent.initializer == expression)) { 169 if (parent is VariableDeclaration && (parent.initializer == expression)) {
189 return new AssignmentCast(rules, expression, cast); 170 return new AssignmentCast(rules, expression, cast);
190 } 171 }
191 172
192 // Other casts 173 // Other casts
193 return new DownCastImplicit(rules, expression, cast); 174 return new DownCastImplicit(rules, expression, cast);
194 } 175 }
195 } 176 }
196 177
197 // 178 //
179 // Implicit down casts. These are only injected by the compiler by flag.
Leaf 2015/12/04 19:32:14 This comment goes with DownCastImplicit.
pquitslund 2015/12/04 23:34:22 Done.
180 //
181
182 // A down cast to a non-ground type. These behave differently from standard
183 // Dart and may be more likely to fail at runtime.
184 class DownCastComposite extends DownCast {
185 DownCastComposite(TypeRules rules, Expression expression, Cast cast)
186 : super._internal(rules, expression, cast);
187
188 @override
189 String get name => 'STRONG_MODE_DOWN_CAST_COMPOSITE';
190
191 toErrorCode() => new StaticTypeWarningCode(name, message);
192 }
193
194 //
198 // Standard down casts. These casts are implicitly injected by the compiler. 195 // Standard down casts. These casts are implicitly injected by the compiler.
Leaf 2015/12/04 19:32:15 This comment goes with DownCast
pquitslund 2015/12/04 23:34:22 `DynamicCast` I think?
199 // 196 //
200 197
201 // A down cast from dynamic to T. 198 // A down cast from dynamic to T.
202 class DynamicCast extends DownCast { 199 class DownCastImplicit extends DownCast {
203 DynamicCast(TypeRules rules, Expression expression, Cast cast) 200 DownCastImplicit(TypeRules rules, Expression expression, Cast cast)
204 : super._internal(rules, expression, cast); 201 : super._internal(rules, expression, cast);
205 202
203 @override
204 String get name => 'STRONG_MODE_DOWN_CAST_IMPLICIT';
205
206 toErrorCode() => new HintCode(name, message); 206 toErrorCode() => new HintCode(name, message);
207 } 207 }
208 208
209 // A down cast due to a variable declaration to a ground type. E.g., 209 // A down cast due to a variable declaration to a ground type. E.g.,
Leaf 2015/12/04 19:32:15 This comment goes with AssignmentCast
pquitslund 2015/12/04 23:34:22 Done.
210 // T x = expr; 210 // T x = expr;
211 // where T is ground. We exclude non-ground types as these behave differently 211 // where T is ground. We exclude non-ground types as these behave differently
212 // compared to standard Dart. 212 // compared to standard Dart.
213 class AssignmentCast extends DownCast { 213 class DynamicCast extends DownCast {
214 AssignmentCast(TypeRules rules, Expression expression, Cast cast) 214 DynamicCast(TypeRules rules, Expression expression, Cast cast)
215 : super._internal(rules, expression, cast); 215 : super._internal(rules, expression, cast);
216 216
217 @override
218 String get name => 'STRONG_MODE_DYNAMIC_CAST';
219
217 toErrorCode() => new HintCode(name, message); 220 toErrorCode() => new HintCode(name, message);
218 } 221 }
219 222
220 // 223 //
221 // Temporary "casts" of allocation sites - literals, constructor invocations, 224 // Temporary "casts" of allocation sites - literals, constructor invocations,
Leaf 2015/12/04 19:32:15 This cast goes with UninferredClosure
pquitslund 2015/12/04 23:34:22 Done.
222 // and closures. These should be handled by contextual inference. In most 225 // and closures. These should be handled by contextual inference. In most
223 // cases, inference will be sufficient, though in some it may unmask an actual 226 // cases, inference will be sufficient, though in some it may unmask an actual
224 // error: e.g., 227 // error: e.g.,
225 // List<int> l = [1, 2, 3]; // Inference succeeds 228 // List<int> l = [1, 2, 3]; // Inference succeeds
226 // List<String> l = [1, 2, 3]; // Inference reveals static type error 229 // List<String> l = [1, 2, 3]; // Inference reveals static type error
227 // We're marking all as warnings for now. 230 // We're marking all as warnings for now.
228 // 231 //
229 // TODO(vsm,leafp): Remove this. 232 // TODO(vsm,leafp): Remove this.
230 class UninferredClosure extends DownCast { 233 class DynamicInvoke extends CoercionInfo {
231 UninferredClosure(TypeRules rules, FunctionExpression expression, Cast cast) 234 static const String _propertyName = 'dev_compiler.src.info.DynamicInvoke';
232 : super._internal(rules, expression, cast);
233 235
234 toErrorCode() => new StaticTypeWarningCode(name, message); 236 DynamicInvoke(TypeRules rules, Expression expression)
237 : super(rules, expression);
238 DartType get convertedType => rules.provider.dynamicType;
239 String get message => '{0} requires dynamic invoke';
240
241 @override
242 String get name => 'STRONG_MODE_DYNAMIC_INVOKE';
243
244 toErrorCode() => new HintCode(name, message);
245
246 /// Whether this [node] is the target of a dynamic operation.
247 static bool get(AstNode node) {
248 var value = node.getProperty(_propertyName);
249 return value != null ? value : false;
250 }
251
252 /// Sets whether this node is the target of a dynamic operation.
253 static bool set(AstNode node, bool value) {
254 // Free the storage for things that aren't dynamic.
255 if (value == false) value = null;
256 node.setProperty(_propertyName, value);
257 return value;
258 }
235 } 259 }
236 260
237 // 261 // The identity coercion
238 // Implicit down casts. These are only injected by the compiler by flag. 262 class Identity extends Coercion {
239 // 263 Identity(DartType fromType) : super(fromType, fromType);
240
241 // A down cast to a non-ground type. These behave differently from standard
242 // Dart and may be more likely to fail at runtime.
243 class DownCastComposite extends DownCast {
244 DownCastComposite(TypeRules rules, Expression expression, Cast cast)
245 : super._internal(rules, expression, cast);
246
247 toErrorCode() => new StaticTypeWarningCode(name, message);
248 } 264 }
249 265
250 // A down cast to a non-ground type. These behave differently from standard 266 // A down cast to a non-ground type. These behave differently from standard
Leaf 2015/12/04 19:32:15 DownCastImplicit
pquitslund 2015/12/04 23:34:22 Done.
251 // Dart and may be more likely to fail at runtime. 267 // Dart and may be more likely to fail at runtime.
252 class DownCastImplicit extends DownCast {
253 DownCastImplicit(TypeRules rules, Expression expression, Cast cast)
254 : super._internal(rules, expression, cast);
255
256 toErrorCode() => new HintCode(name, message);
257 }
258
259 // An inferred type for the wrapped expression, which may need to be
260 // reified into the term
261 abstract class InferredTypeBase extends CoercionInfo {
262 final DartType _type;
263
264 InferredTypeBase._internal(TypeRules rules, Expression expression, this._type)
265 : super(rules, expression);
266
267 DartType get type => _type;
268 DartType get convertedType => type;
269 @override String get message => '{0} has inferred type {1}';
270 @override List get arguments => [node, type];
271
272 toErrorCode() => new HintCode(name, message);
273 }
274
275 // Standard / unspecialized inferred type
276 class InferredType extends InferredTypeBase { 268 class InferredType extends InferredTypeBase {
277 InferredType(TypeRules rules, Expression expression, DartType type) 269 InferredType(TypeRules rules, Expression expression, DartType type)
278 : super._internal(rules, expression, type); 270 : super._internal(rules, expression, type);
279 271
280 // Factory to create correct InferredType variant. 272 // Factory to create correct InferredType variant.
Leaf 2015/12/04 19:32:14 This goes with the create Factory
pquitslund 2015/12/04 23:34:22 Done.
273 @override
274 String get name => 'STRONG_MODE_INFERRED_TYPE';
275
281 static InferredTypeBase create( 276 static InferredTypeBase create(
282 TypeRules rules, Expression expression, DartType type) { 277 TypeRules rules, Expression expression, DartType type) {
283 // Specialized inference: 278 // Specialized inference:
284 if (expression is Literal) { 279 if (expression is Literal) {
285 return new InferredTypeLiteral(rules, expression, type); 280 return new InferredTypeLiteral(rules, expression, type);
286 } 281 }
287 if (expression is InstanceCreationExpression) { 282 if (expression is InstanceCreationExpression) {
288 return new InferredTypeAllocation(rules, expression, type); 283 return new InferredTypeAllocation(rules, expression, type);
289 } 284 }
290 if (expression is FunctionExpression) { 285 if (expression is FunctionExpression) {
291 return new InferredTypeClosure(rules, expression, type); 286 return new InferredTypeClosure(rules, expression, type);
292 } 287 }
293 return new InferredType(rules, expression, type); 288 return new InferredType(rules, expression, type);
294 } 289 }
295 } 290 }
296 291
297 // An infered type for a literal expression. 292 // An inferred type for the wrapped expression, which may need to be
298 class InferredTypeLiteral extends InferredTypeBase { 293 // reified into the term
Leaf 2015/12/04 19:32:14 InferredTypeBase
pquitslund 2015/12/04 23:34:22 Done.
299 InferredTypeLiteral(TypeRules rules, Expression expression, DartType type)
300 : super._internal(rules, expression, type);
301 }
302
303 // An inferred type for a non-literal allocation site.
304 class InferredTypeAllocation extends InferredTypeBase { 294 class InferredTypeAllocation extends InferredTypeBase {
305 InferredTypeAllocation(TypeRules rules, Expression expression, DartType type) 295 InferredTypeAllocation(TypeRules rules, Expression expression, DartType type)
306 : super._internal(rules, expression, type); 296 : super._internal(rules, expression, type);
297
298 @override
299 String get name => 'STRONG_MODE_INFERRED_TYPE_ALLOCATION';
307 } 300 }
308 301
309 // An inferred type for a closure expression 302 // Standard / unspecialized inferred type
Leaf 2015/12/04 19:32:14 InferredType.
pquitslund 2015/12/04 23:34:22 Done.
310 class InferredTypeClosure extends InferredTypeBase { 303 abstract class InferredTypeBase extends CoercionInfo {
311 InferredTypeClosure(TypeRules rules, Expression expression, DartType type) 304 final DartType _type;
312 : super._internal(rules, expression, type);
313 }
314 305
315 class DynamicInvoke extends CoercionInfo { 306 InferredTypeBase._internal(TypeRules rules, Expression expression, this._type)
316 DynamicInvoke(TypeRules rules, Expression expression)
317 : super(rules, expression); 307 : super(rules, expression);
318 308
319 DartType get convertedType => rules.provider.dynamicType; 309 @override List get arguments => [node, type];
320 String get message => '{0} requires dynamic invoke'; 310 DartType get convertedType => type;
321 toErrorCode() => new HintCode(name, message); 311 @override String get message => '{0} has inferred type {1}';
322 312 DartType get type => _type;
323 static const String _propertyName = 'dev_compiler.src.info.DynamicInvoke';
324
325 /// Whether this [node] is the target of a dynamic operation.
326 static bool get(AstNode node) {
327 var value = node.getProperty(_propertyName);
328 return value != null ? value : false;
329 }
330
331 /// Sets whether this node is the target of a dynamic operation.
332 static bool set(AstNode node, bool value) {
333 // Free the storage for things that aren't dynamic.
334 if (value == false) value = null;
335 node.setProperty(_propertyName, value);
336 return value;
337 }
338 }
339
340 abstract class StaticError extends StaticInfo {
341 final AstNode node;
342
343 StaticError(this.node);
344
345 String get message;
346
347 toErrorCode() => new CompileTimeErrorCode(name, message);
348 }
349
350 class StaticTypeError extends StaticError {
351 final DartType baseType;
352 final DartType expectedType;
353 String reason = null;
354
355 StaticTypeError(TypeRules rules, Expression expression, this.expectedType,
356 {this.reason})
357 : baseType = rules.getStaticType(expression),
358 super(expression);
359
360 @override List<Object> get arguments => [node, baseType, expectedType];
361 @override String get message =>
362 'Type check failed: {0} ({1}) is not of type {2}' +
363 ((reason == null) ? '' : ' because $reason');
364 }
365
366 class InvalidVariableDeclaration extends StaticError {
367 final DartType expectedType;
368
369 InvalidVariableDeclaration(
370 TypeRules rules, AstNode declaration, this.expectedType)
371 : super(declaration);
372
373 @override List<Object> get arguments => [expectedType];
374 @override String get message => 'Type check failed: null is not of type {0}';
375 }
376
377 class InvalidParameterDeclaration extends StaticError {
378 final DartType expectedType;
379
380 InvalidParameterDeclaration(
381 TypeRules rules, FormalParameter declaration, this.expectedType)
382 : super(declaration);
383
384 @override List<Object> get arguments => [node, expectedType];
385 @override String get message => 'Type check failed: {0} is not of type {1}';
386 }
387
388 class NonGroundTypeCheckInfo extends StaticInfo {
389 final DartType type;
390 final AstNode node;
391
392 NonGroundTypeCheckInfo(this.node, this.type) {
393 assert(node is IsExpression || node is AsExpression);
394 }
395
396 @override List<Object> get arguments => [type];
397 String get message =>
398 "Runtime check on non-ground type {0} may throw StrongModeError";
399 313
400 toErrorCode() => new HintCode(name, message); 314 toErrorCode() => new HintCode(name, message);
401 } 315 }
402 316
403 // Invalid override of an instance member of a class. 317 // An inferred type for a literal expression.
Leaf 2015/12/04 19:32:14 InferredTypeLiteral
pquitslund 2015/12/04 23:34:22 Done.
318 class InferredTypeClosure extends InferredTypeBase {
319 InferredTypeClosure(TypeRules rules, Expression expression, DartType type)
320 : super._internal(rules, expression, type);
321
322 @override
323 String get name => 'STRONG_MODE_INFERRED_TYPE_CLOSURE';
324 }
325
326 // An inferred type for a non-literal allocation site.
Leaf 2015/12/04 19:32:14 InferredTypeAllocation
pquitslund 2015/12/04 23:34:22 Done.
327 class InferredTypeLiteral extends InferredTypeBase {
328 InferredTypeLiteral(TypeRules rules, Expression expression, DartType type)
329 : super._internal(rules, expression, type);
330
331 @override
332 String get name => 'STRONG_MODE_INFERRED_TYPE_LITERAL';
333 }
334
335 // An inferred type for a closure expression
Leaf 2015/12/04 19:32:15 InferredTypeClosure
pquitslund 2015/12/04 23:34:22 Done.
336 class InvalidFieldOverride extends InvalidOverride {
337 InvalidFieldOverride(AstNode node, ExecutableElement element,
338 InterfaceType base, DartType subType, DartType baseType)
339 : super(node, element, base, subType, baseType);
340
341 String get message => 'Field declaration {3}.{1} cannot be '
342 'overridden in {0}.';
343
344 @override
345 String get name => 'STRONG_MODE_INVALID_FIELD_OVERRIDE';
346 }
347
348 // Invalid override due to incompatible type. I.e., the overridden signature
Leaf 2015/12/04 19:32:14 InvalidFieldOverride
pquitslund 2015/12/04 23:34:22 Done.
349 // is not compatible with the original.
350 class InvalidMethodOverride extends InvalidOverride {
351 InvalidMethodOverride(AstNode node, ExecutableElement element,
352 InterfaceType base, FunctionType subType, FunctionType baseType)
353 : super(node, element, base, subType, baseType);
354
355 String get message => _messageHelper('Invalid override');
356
357 @override
358 String get name => 'STRONG_MODE_INVALID_METHOD_OVERRIDE';
359 }
360
404 abstract class InvalidOverride extends StaticError { 361 abstract class InvalidOverride extends StaticError {
405 /// Member declaration with the invalid override. 362 /// Member declaration with the invalid override.
406 final ExecutableElement element; 363 final ExecutableElement element;
407 364
408 /// Type (class or interface) that provides the base declaration. 365 /// Type (class or interface) that provides the base declaration.
409 final InterfaceType base; 366 final InterfaceType base;
410 367
411 /// Actual type of the overridden member. 368 /// Actual type of the overridden member.
412 final DartType subType; 369 final DartType subType;
413 370
414 /// Actual type of the base member. 371 /// Actual type of the base member.
415 final DartType baseType; 372 final DartType baseType;
416 373
417 /// Whether the error comes from combining a base class and an interface 374 /// Whether the error comes from combining a base class and an interface
418 final bool fromBaseClass; 375 final bool fromBaseClass;
419 376
420 /// Whether the error comes from a mixin (either overriding a base class or an 377 /// Whether the error comes from a mixin (either overriding a base class or an
421 /// interface declaration). 378 /// interface declaration).
422 final bool fromMixin; 379 final bool fromMixin;
423 380
424 InvalidOverride( 381 InvalidOverride(
425 AstNode node, this.element, this.base, this.subType, this.baseType) 382 AstNode node, this.element, this.base, this.subType, this.baseType)
426 : fromBaseClass = node is ExtendsClause, 383 : fromBaseClass = node is ExtendsClause,
427 fromMixin = node.parent is WithClause, 384 fromMixin = node.parent is WithClause,
428 super(node); 385 super(node);
429 386
430 ClassElement get parent => element.enclosingElement;
431
432 @override List<Object> get arguments => 387 @override List<Object> get arguments =>
433 [parent.name, element.name, subType, base, baseType]; 388 [parent.name, element.name, subType, base, baseType];
434 389
390 ClassElement get parent => element.enclosingElement;
391
435 String _messageHelper(String errorName) { 392 String _messageHelper(String errorName) {
436 var lcErrorName = errorName.toLowerCase(); 393 var lcErrorName = errorName.toLowerCase();
437 var intro = fromBaseClass 394 var intro = fromBaseClass
438 ? 'Base class introduces an $lcErrorName' 395 ? 'Base class introduces an $lcErrorName'
439 : (fromMixin ? 'Mixin introduces an $lcErrorName' : errorName); 396 : (fromMixin ? 'Mixin introduces an $lcErrorName' : errorName);
440 return '$intro. The type of {0}.{1} ({2}) is not a ' 397 return '$intro. The type of {0}.{1} ({2}) is not a '
441 'subtype of {3}.{1} ({4}).'; 398 'subtype of {3}.{1} ({4}).';
442 } 399 }
443 } 400 }
444 401
445 // Invalid override due to incompatible type. I.e., the overridden signature 402 class InvalidParameterDeclaration extends StaticError {
446 // is not compatible with the original. 403 final DartType expectedType;
447 class InvalidMethodOverride extends InvalidOverride {
448 InvalidMethodOverride(AstNode node, ExecutableElement element,
449 InterfaceType base, FunctionType subType, FunctionType baseType)
450 : super(node, element, base, subType, baseType);
451 404
452 String get message => _messageHelper('Invalid override'); 405 InvalidParameterDeclaration(
453 } 406 TypeRules rules, FormalParameter declaration, this.expectedType)
407 : super(declaration);
454 408
455 class InvalidFieldOverride extends InvalidOverride { 409 @override List<Object> get arguments => [node, expectedType];
456 InvalidFieldOverride(AstNode node, ExecutableElement element, 410 @override String get message => 'Type check failed: {0} is not of type {1}';
457 InterfaceType base, DartType subType, DartType baseType) 411 @override
458 : super(node, element, base, subType, baseType); 412 String get name => 'STRONG_MODE_INVALID_PARAMETER_DECLARATION';
459
460 String get message => 'Field declaration {3}.{1} cannot be '
461 'overridden in {0}.';
462 } 413 }
463 414
464 /// Dart constructors have one weird quirk, illustrated with this example: 415 /// Dart constructors have one weird quirk, illustrated with this example:
465 /// 416 ///
466 /// class Base { 417 /// class Base {
467 /// var x; 418 /// var x;
468 /// Base() : x = print('Base.1') { 419 /// Base() : x = print('Base.1') {
469 /// print('Base.2'); 420 /// print('Base.2');
470 /// } 421 /// }
471 /// } 422 /// }
(...skipping 16 matching lines...) Expand all
488 /// 439 ///
489 /// Better to have `super` at the end, as required by the Dart style guide: 440 /// Better to have `super` at the end, as required by the Dart style guide:
490 /// <http://goo.gl/q1T4BB> 441 /// <http://goo.gl/q1T4BB>
491 /// 442 ///
492 /// For now this is the only pattern we support. 443 /// For now this is the only pattern we support.
493 class InvalidSuperInvocation extends StaticError { 444 class InvalidSuperInvocation extends StaticError {
494 InvalidSuperInvocation(SuperConstructorInvocation node) : super(node); 445 InvalidSuperInvocation(SuperConstructorInvocation node) : super(node);
495 446
496 @override String get message => "super call must be last in an initializer " 447 @override String get message => "super call must be last in an initializer "
497 "list (see http://goo.gl/q1T4BB): {0}"; 448 "list (see http://goo.gl/q1T4BB): {0}";
449
450 @override
451 String get name => 'STRONG_MODE_INVALID_SUPER_INVOCATION';
498 } 452 }
453
454 class InvalidVariableDeclaration extends StaticError {
455 final DartType expectedType;
456
457 InvalidVariableDeclaration(
458 TypeRules rules, AstNode declaration, this.expectedType)
459 : super(declaration);
460
461 @override List<Object> get arguments => [expectedType];
462 @override String get message => 'Type check failed: null is not of type {0}';
463
464 @override
465 String get name => 'STRONG_MODE_INVALID_VARIABLE_DECLARATION';
466 }
467
468 class NonGroundTypeCheckInfo extends StaticInfo {
469 final DartType type;
470 final AstNode node;
471
472 NonGroundTypeCheckInfo(this.node, this.type) {
473 assert(node is IsExpression || node is AsExpression);
474 }
475
476 @override List<Object> get arguments => [type];
477 String get message =>
478 "Runtime check on non-ground type {0} may throw StrongModeError";
479
480 @override
481 String get name => 'STRONG_MODE_NON_GROUND_TYPE_CHECK_INFO';
482
483 toErrorCode() => new HintCode(name, message);
484 }
485
486 // Invalid override of an instance member of a class.
Leaf 2015/12/04 19:32:15 InvalidOverride
pquitslund 2015/12/04 23:34:22 Done.
487 abstract class StaticError extends StaticInfo {
488 final AstNode node;
489
490 StaticError(this.node);
491
492 String get message;
493
494 toErrorCode() => new CompileTimeErrorCode(name, message);
495 }
496
497 // TODO(jmesserly): this could use some refactoring. These are essentially
498 // like ErrorCodes in analyzer, but we're including some details in our message.
499 // Analyzer instead has template strings, and replaces '{0}' with the first
500 // argument.
501 abstract class StaticInfo {
502 List<Object> get arguments => [node];
503
504 // TODO(jmesserly): review the usage of error codes. We probably want our own,
505 // as well as some DDC specific [ErrorType]s.
Leaf 2015/12/04 19:32:14 toErrorCode
pquitslund 2015/12/04 23:34:22 Done.
506 String get name;
507
508 /// AST Node this info is attached to.
509 AstNode get node;
510
511 AnalysisError toAnalysisError() {
512 int begin = node is AnnotatedNode
513 ? (node as AnnotatedNode).firstTokenAfterCommentAndMetadata.offset
514 : node.offset;
515 int length = node.end - begin;
516 var source = (node.root as CompilationUnit).element.source;
517 return new AnalysisError(source, begin, length, toErrorCode(), arguments);
518 }
519
520 ErrorCode toErrorCode();
521 }
522
523 class StaticTypeError extends StaticError {
524 final DartType baseType;
525 final DartType expectedType;
526 String reason = null;
527
528 StaticTypeError(TypeRules rules, Expression expression, this.expectedType,
529 {this.reason})
530 : baseType = rules.getStaticType(expression),
531 super(expression);
532
533 @override List<Object> get arguments => [node, baseType, expectedType];
534 @override String get message =>
535 'Type check failed: {0} ({1}) is not of type {2}' +
536 ((reason == null) ? '' : ' because $reason');
537
538 @override
539 String get name => 'STRONG_MODE_STATIC_TYPE_ERROR';
540 }
541
542 class UninferredClosure extends DownCast {
543 UninferredClosure(TypeRules rules, FunctionExpression expression, Cast cast)
544 : super._internal(rules, expression, cast);
545
546 @override
547 String get name => 'STRONG_MODE_UNINFERRED_CLOSURE';
548
549 toErrorCode() => new StaticTypeWarningCode(name, message);
550 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/task/dart_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698