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 library dev_compiler.src.checker.checker; | 5 library dev_compiler.src.checker.checker; |
6 | 6 |
7 import 'package:analyzer/analyzer.dart'; | 7 import 'package:analyzer/analyzer.dart'; |
8 import 'package:analyzer/src/generated/ast.dart'; | 8 import 'package:analyzer/src/generated/ast.dart'; |
9 import 'package:analyzer/src/generated/element.dart'; | 9 import 'package:analyzer/src/generated/element.dart'; |
10 import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType; | 10 import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType; |
11 import 'package:logging/logging.dart' as logger; | |
12 | 11 |
13 import 'package:dev_compiler/src/info.dart'; | 12 import 'package:dev_compiler/src/info.dart'; |
14 import 'package:dev_compiler/src/report.dart' show CheckerReporter; | |
15 import 'package:dev_compiler/src/utils.dart' show getMemberType; | 13 import 'package:dev_compiler/src/utils.dart' show getMemberType; |
16 import 'package:dev_compiler/strong_mode.dart' show StrongModeOptions; | 14 import 'package:dev_compiler/strong_mode.dart' show StrongModeOptions; |
17 import 'rules.dart'; | 15 import 'rules.dart'; |
18 | 16 |
19 /// Checks for overriding declarations of fields and methods. This is used to | 17 /// Checks for overriding declarations of fields and methods. This is used to |
20 /// check overrides between classes and superclasses, interfaces, and mixin | 18 /// check overrides between classes and superclasses, interfaces, and mixin |
21 /// applications. | 19 /// applications. |
22 class _OverrideChecker { | 20 class _OverrideChecker { |
23 bool _failure = false; | 21 bool _failure = false; |
24 final TypeRules _rules; | 22 final TypeRules _rules; |
25 final CheckerReporter _reporter; | 23 final AnalysisErrorListener _reporter; |
26 final bool _inferFromOverrides; | 24 final bool _inferFromOverrides; |
27 _OverrideChecker(this._rules, this._reporter, StrongModeOptions options) | 25 _OverrideChecker(this._rules, this._reporter, StrongModeOptions options) |
28 : _inferFromOverrides = options.inferFromOverrides; | 26 : _inferFromOverrides = options.inferFromOverrides; |
29 | 27 |
30 void check(ClassDeclaration node) { | 28 void check(ClassDeclaration node) { |
31 if (node.element.type.isObject) return; | 29 if (node.element.type.isObject) return; |
32 _checkSuperOverrides(node); | 30 _checkSuperOverrides(node); |
33 _checkMixinApplicationOverrides(node); | 31 _checkMixinApplicationOverrides(node); |
34 _checkAllInterfaceOverrides(node); | 32 _checkAllInterfaceOverrides(node); |
35 } | 33 } |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 // node is a MethodDeclaration whenever getters and setters are | 318 // node is a MethodDeclaration whenever getters and setters are |
321 // declared explicitly. Setters declared from a field will have the | 319 // declared explicitly. Setters declared from a field will have the |
322 // correct return type, so we don't need to check that separately. | 320 // correct return type, so we don't need to check that separately. |
323 return node is MethodDeclaration && | 321 return node is MethodDeclaration && |
324 node.returnType == null && | 322 node.returnType == null && |
325 _rules.isFunctionSubTypeOf(subType, baseType, ignoreReturn: true); | 323 _rules.isFunctionSubTypeOf(subType, baseType, ignoreReturn: true); |
326 } | 324 } |
327 | 325 |
328 void _recordMessage(StaticInfo info) { | 326 void _recordMessage(StaticInfo info) { |
329 if (info == null) return; | 327 if (info == null) return; |
330 if (info.level >= logger.Level.SEVERE) _failure = true; | 328 var error = info.toAnalysisError(); |
331 _reporter.log(info); | 329 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) _failure = true; |
| 330 _reporter.onError(error); |
332 } | 331 } |
333 } | 332 } |
334 | 333 |
335 /// Checks the body of functions and properties. | 334 /// Checks the body of functions and properties. |
336 class CodeChecker extends RecursiveAstVisitor { | 335 class CodeChecker extends RecursiveAstVisitor { |
337 final TypeRules _rules; | 336 final TypeRules _rules; |
338 final CheckerReporter _reporter; | 337 final AnalysisErrorListener _reporter; |
339 final _OverrideChecker _overrideChecker; | 338 final _OverrideChecker _overrideChecker; |
340 bool _failure = false; | 339 bool _failure = false; |
341 bool get failure => _failure || _overrideChecker._failure; | 340 bool get failure => _failure || _overrideChecker._failure; |
342 | 341 |
343 CodeChecker( | 342 CodeChecker(TypeRules rules, AnalysisErrorListener reporter, |
344 TypeRules rules, CheckerReporter reporter, StrongModeOptions options) | 343 StrongModeOptions options) |
345 : _rules = rules, | 344 : _rules = rules, |
346 _reporter = reporter, | 345 _reporter = reporter, |
347 _overrideChecker = new _OverrideChecker(rules, reporter, options); | 346 _overrideChecker = new _OverrideChecker(rules, reporter, options); |
348 | 347 |
349 @override | 348 @override |
350 void visitCompilationUnit(CompilationUnit unit) { | 349 void visitCompilationUnit(CompilationUnit unit) { |
351 void report(Expression expr) { | 350 void report(Expression expr) { |
352 _reporter.log(new MissingTypeError(expr)); | 351 _reporter.onError(new MissingTypeError(expr).toAnalysisError()); |
353 } | 352 } |
354 var callback = _rules.reportMissingType; | 353 var callback = _rules.reportMissingType; |
355 _rules.reportMissingType = report; | 354 _rules.reportMissingType = report; |
356 unit.visitChildren(this); | 355 unit.visitChildren(this); |
357 _rules.reportMissingType = callback; | 356 _rules.reportMissingType = callback; |
358 } | 357 } |
359 | 358 |
360 @override | 359 @override |
361 void visitComment(Comment node) { | 360 void visitComment(Comment node) { |
362 // skip, no need to do typechecking inside comments (they may contain | 361 // skip, no need to do typechecking inside comments (they may contain |
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 // Check the rhs type | 980 // Check the rhs type |
982 if (staticInfo is! CoercionInfo) { | 981 if (staticInfo is! CoercionInfo) { |
983 var paramType = paramTypes.first; | 982 var paramType = paramTypes.first; |
984 staticInfo = _rules.checkAssignment(expr.rightHandSide, paramType); | 983 staticInfo = _rules.checkAssignment(expr.rightHandSide, paramType); |
985 _recordMessage(staticInfo); | 984 _recordMessage(staticInfo); |
986 } | 985 } |
987 } | 986 } |
988 } | 987 } |
989 | 988 |
990 void _recordDynamicInvoke(AstNode node, AstNode target) { | 989 void _recordDynamicInvoke(AstNode node, AstNode target) { |
991 var dinvoke = new DynamicInvoke(_rules, node); | 990 _reporter.onError(new DynamicInvoke(_rules, node).toAnalysisError()); |
992 _reporter.log(dinvoke); | |
993 // TODO(jmesserly): we may eventually want to record if the whole operation | 991 // TODO(jmesserly): we may eventually want to record if the whole operation |
994 // (node) was dynamic, rather than the target, but this is an easier fit | 992 // (node) was dynamic, rather than the target, but this is an easier fit |
995 // with what we used to do. | 993 // with what we used to do. |
996 DynamicInvoke.set(target, true); | 994 DynamicInvoke.set(target, true); |
997 } | 995 } |
998 | 996 |
999 void _recordMessage(StaticInfo info) { | 997 void _recordMessage(StaticInfo info) { |
1000 if (info == null) return; | 998 if (info == null) return; |
1001 if (info.level >= logger.Level.SEVERE) _failure = true; | 999 var error = info.toAnalysisError(); |
1002 _reporter.log(info); | 1000 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) _failure = true; |
| 1001 _reporter.onError(error); |
| 1002 |
1003 if (info is CoercionInfo) { | 1003 if (info is CoercionInfo) { |
1004 assert(CoercionInfo.get(info.node) == null); | 1004 assert(CoercionInfo.get(info.node) == null); |
1005 CoercionInfo.set(info.node, info); | 1005 CoercionInfo.set(info.node, info); |
1006 } | 1006 } |
1007 } | 1007 } |
1008 } | 1008 } |
OLD | NEW |