| 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 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be | 5 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be |
| 6 // refactored to fit into analyzer. | 6 // refactored to fit into analyzer. |
| 7 library analyzer.src.task.strong.checker; | 7 library analyzer.src.task.strong.checker; |
| 8 | 8 |
| 9 import 'package:analyzer/analyzer.dart'; | 9 import 'package:analyzer/analyzer.dart'; |
| 10 import 'package:analyzer/src/generated/ast.dart'; | 10 import 'package:analyzer/src/generated/ast.dart'; |
| 11 import 'package:analyzer/src/generated/element.dart'; | 11 import 'package:analyzer/src/generated/element.dart'; |
| 12 import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType; | 12 import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType; |
| 13 | 13 |
| 14 import 'info.dart'; | 14 import 'info.dart'; |
| 15 import 'rules.dart'; | 15 import 'rules.dart'; |
| 16 | 16 |
| 17 /// 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 |
| 18 /// check overrides between classes and superclasses, interfaces, and mixin | 18 /// check overrides between classes and superclasses, interfaces, and mixin |
| 19 /// applications. | 19 /// applications. |
| 20 class _OverrideChecker { | 20 class _OverrideChecker { |
| 21 bool _failure = false; | 21 bool _failure = false; |
| 22 final TypeRules _rules; | 22 final TypeRules _rules; |
| 23 final ErrorReporter _reporter; | 23 final AnalysisErrorListener _reporter; |
| 24 | 24 |
| 25 _OverrideChecker(this._rules, this._reporter); | 25 _OverrideChecker(this._rules, this._reporter); |
| 26 | 26 |
| 27 void check(ClassDeclaration node) { | 27 void check(ClassDeclaration node) { |
| 28 if (node.element.type.isObject) return; | 28 if (node.element.type.isObject) return; |
| 29 _checkSuperOverrides(node); | 29 _checkSuperOverrides(node); |
| 30 _checkMixinApplicationOverrides(node); | 30 _checkMixinApplicationOverrides(node); |
| 31 _checkAllInterfaceOverrides(node); | 31 _checkAllInterfaceOverrides(node); |
| 32 } | 32 } |
| 33 | 33 |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 _recordMessage(new InvalidMethodOverride( | 311 _recordMessage(new InvalidMethodOverride( |
| 312 errorLocation, element, type, subType, baseType)); | 312 errorLocation, element, type, subType, baseType)); |
| 313 } | 313 } |
| 314 return true; | 314 return true; |
| 315 } | 315 } |
| 316 | 316 |
| 317 void _recordMessage(StaticInfo info) { | 317 void _recordMessage(StaticInfo info) { |
| 318 if (info == null) return; | 318 if (info == null) return; |
| 319 var error = info.toAnalysisError(); | 319 var error = info.toAnalysisError(); |
| 320 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) _failure = true; | 320 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) _failure = true; |
| 321 _reporter.reportError(error); | 321 _reporter.onError(error); |
| 322 } | 322 } |
| 323 } | 323 } |
| 324 | 324 |
| 325 /// Checks the body of functions and properties. | 325 /// Checks the body of functions and properties. |
| 326 class CodeChecker extends RecursiveAstVisitor { | 326 class CodeChecker extends RecursiveAstVisitor { |
| 327 final TypeRules rules; | 327 final TypeRules rules; |
| 328 final ErrorReporter reporter; | 328 final AnalysisErrorListener reporter; |
| 329 final _OverrideChecker _overrideChecker; | 329 final _OverrideChecker _overrideChecker; |
| 330 bool _failure = false; | 330 bool _failure = false; |
| 331 bool get failure => _failure || _overrideChecker._failure; | 331 bool get failure => _failure || _overrideChecker._failure; |
| 332 | 332 |
| 333 void reset() { | 333 void reset() { |
| 334 _failure = false; | 334 _failure = false; |
| 335 _overrideChecker._failure = false; | 335 _overrideChecker._failure = false; |
| 336 } | 336 } |
| 337 | 337 |
| 338 CodeChecker(TypeRules rules, ErrorReporter reporter) | 338 CodeChecker(TypeRules rules, AnalysisErrorListener reporter) |
| 339 : rules = rules, | 339 : rules = rules, |
| 340 reporter = reporter, | 340 reporter = reporter, |
| 341 _overrideChecker = new _OverrideChecker(rules, reporter); | 341 _overrideChecker = new _OverrideChecker(rules, reporter); |
| 342 | 342 |
| 343 @override | 343 @override |
| 344 void visitComment(Comment node) { | 344 void visitComment(Comment node) { |
| 345 // skip, no need to do typechecking inside comments (they may contain | 345 // skip, no need to do typechecking inside comments (they may contain |
| 346 // comment references which would require resolution). | 346 // comment references which would require resolution). |
| 347 } | 347 } |
| 348 | 348 |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 return (element != null && !element.isStatic); | 911 return (element != null && !element.isStatic); |
| 912 } | 912 } |
| 913 | 913 |
| 914 bool _isObjectProperty(Expression target, SimpleIdentifier id) { | 914 bool _isObjectProperty(Expression target, SimpleIdentifier id) { |
| 915 return _isObjectGetter(target, id) || _isObjectMethod(target, id); | 915 return _isObjectGetter(target, id) || _isObjectMethod(target, id); |
| 916 } | 916 } |
| 917 | 917 |
| 918 DartType _getStaticType(Expression expr) { | 918 DartType _getStaticType(Expression expr) { |
| 919 var type = expr.staticType; | 919 var type = expr.staticType; |
| 920 if (type == null) { | 920 if (type == null) { |
| 921 reporter.reportError(new MissingTypeError(expr).toAnalysisError()); | 921 reporter.onError(new MissingTypeError(expr).toAnalysisError()); |
| 922 } | 922 } |
| 923 return type ?? rules.provider.dynamicType; | 923 return type ?? rules.provider.dynamicType; |
| 924 } | 924 } |
| 925 | 925 |
| 926 void _recordDynamicInvoke(AstNode node, AstNode target) { | 926 void _recordDynamicInvoke(AstNode node, AstNode target) { |
| 927 reporter.reportError(new DynamicInvoke(rules, node).toAnalysisError()); | 927 reporter.onError(new DynamicInvoke(rules, node).toAnalysisError()); |
| 928 // TODO(jmesserly): we may eventually want to record if the whole operation | 928 // TODO(jmesserly): we may eventually want to record if the whole operation |
| 929 // (node) was dynamic, rather than the target, but this is an easier fit | 929 // (node) was dynamic, rather than the target, but this is an easier fit |
| 930 // with what we used to do. | 930 // with what we used to do. |
| 931 DynamicInvoke.set(target, true); | 931 DynamicInvoke.set(target, true); |
| 932 } | 932 } |
| 933 | 933 |
| 934 void _recordMessage(StaticInfo info) { | 934 void _recordMessage(StaticInfo info) { |
| 935 if (info == null) return; | 935 if (info == null) return; |
| 936 var error = info.toAnalysisError(); | 936 var error = info.toAnalysisError(); |
| 937 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) _failure = true; | 937 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) _failure = true; |
| 938 reporter.reportError(error); | 938 reporter.onError(error); |
| 939 | 939 |
| 940 if (info is CoercionInfo) { | 940 if (info is CoercionInfo) { |
| 941 // TODO(jmesserly): if we're run again on the same AST, we'll produce the | 941 // TODO(jmesserly): if we're run again on the same AST, we'll produce the |
| 942 // same annotations. This should be harmless. This might go away once | 942 // same annotations. This should be harmless. This might go away once |
| 943 // CodeChecker is integrated better with analyzer, as it will know that | 943 // CodeChecker is integrated better with analyzer, as it will know that |
| 944 // checking has already been performed. | 944 // checking has already been performed. |
| 945 // assert(CoercionInfo.get(info.node) == null); | 945 // assert(CoercionInfo.get(info.node) == null); |
| 946 CoercionInfo.set(info.node, info); | 946 CoercionInfo.set(info.node, info); |
| 947 } | 947 } |
| 948 } | 948 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 975 } | 975 } |
| 976 } catch (e) { | 976 } catch (e) { |
| 977 // TODO(sigmund): remove this try-catch block (see issue #48). | 977 // TODO(sigmund): remove this try-catch block (see issue #48). |
| 978 } | 978 } |
| 979 if (baseMethod == null || baseMethod.isStatic) return null; | 979 if (baseMethod == null || baseMethod.isStatic) return null; |
| 980 return baseMethod.type; | 980 return baseMethod.type; |
| 981 } | 981 } |
| 982 ; | 982 ; |
| 983 return f; | 983 return f; |
| 984 } | 984 } |
| OLD | NEW |