| 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 |