| 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; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 if (interfaceType == null || interfaceType.isObject) return; | 113 if (interfaceType == null || interfaceType.isObject) return; |
| 114 if (result.contains(interfaceType)) return; | 114 if (result.contains(interfaceType)) return; |
| 115 result.add(interfaceType); | 115 result.add(interfaceType); |
| 116 find(interfaceType.superclass, result); | 116 find(interfaceType.superclass, result); |
| 117 interfaceType.mixins.forEach((i) => find(i, result)); | 117 interfaceType.mixins.forEach((i) => find(i, result)); |
| 118 interfaceType.interfaces.forEach((i) => find(i, result)); | 118 interfaceType.interfaces.forEach((i) => find(i, result)); |
| 119 } | 119 } |
| 120 | 120 |
| 121 // Check all interfaces reachable from the `implements` clause in the | 121 // Check all interfaces reachable from the `implements` clause in the |
| 122 // current class against definitions here and in superclasses. | 122 // current class against definitions here and in superclasses. |
| 123 var localInterfaces = new Set(); | 123 var localInterfaces = new Set<InterfaceType>(); |
| 124 var type = node.element.type; | 124 var type = node.element.type; |
| 125 type.interfaces.forEach((i) => find(i, localInterfaces)); | 125 type.interfaces.forEach((i) => find(i, localInterfaces)); |
| 126 _checkInterfacesOverrides(node, localInterfaces, seen, | 126 _checkInterfacesOverrides(node, localInterfaces, seen, |
| 127 includeParents: true); | 127 includeParents: true); |
| 128 | 128 |
| 129 // Check also how we override locally the interfaces from parent classes if | 129 // Check also how we override locally the interfaces from parent classes if |
| 130 // the parent class is abstract. Otherwise, these will be checked as | 130 // the parent class is abstract. Otherwise, these will be checked as |
| 131 // overrides on the concrete superclass. | 131 // overrides on the concrete superclass. |
| 132 var superInterfaces = new Set(); | 132 var superInterfaces = new Set<InterfaceType>(); |
| 133 var parent = type.superclass; | 133 var parent = type.superclass; |
| 134 // TODO(sigmund): we don't seem to be reporting the analyzer error that a | 134 // TODO(sigmund): we don't seem to be reporting the analyzer error that a |
| 135 // non-abstract class is not implementing an interface. See | 135 // non-abstract class is not implementing an interface. See |
| 136 // https://github.com/dart-lang/dart-dev-compiler/issues/25 | 136 // https://github.com/dart-lang/dart-dev-compiler/issues/25 |
| 137 while (parent != null && parent.element.isAbstract) { | 137 while (parent != null && parent.element.isAbstract) { |
| 138 parent.interfaces.forEach((i) => find(i, superInterfaces)); | 138 parent.interfaces.forEach((i) => find(i, superInterfaces)); |
| 139 parent = parent.superclass; | 139 parent = parent.superclass; |
| 140 } | 140 } |
| 141 _checkInterfacesOverrides(node, superInterfaces, seen, | 141 _checkInterfacesOverrides(node, superInterfaces, seen, |
| 142 includeParents: false); | 142 includeParents: false); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 var setter = element.setter; | 232 var setter = element.setter; |
| 233 bool found = _checkSingleOverride(getter, baseType, variable, member); | 233 bool found = _checkSingleOverride(getter, baseType, variable, member); |
| 234 if (!variable.isFinal && | 234 if (!variable.isFinal && |
| 235 _checkSingleOverride(setter, baseType, variable, member)) { | 235 _checkSingleOverride(setter, baseType, variable, member)) { |
| 236 found = true; | 236 found = true; |
| 237 } | 237 } |
| 238 if (found) seen.add(name); | 238 if (found) seen.add(name); |
| 239 } | 239 } |
| 240 } else { | 240 } else { |
| 241 if ((member as MethodDeclaration).isStatic) continue; | 241 if ((member as MethodDeclaration).isStatic) continue; |
| 242 var method = member.element; | 242 var method = (member as MethodDeclaration).element; |
| 243 if (seen.contains(method.name)) continue; | 243 if (seen.contains(method.name)) continue; |
| 244 if (_checkSingleOverride(method, baseType, member, member)) { | 244 if (_checkSingleOverride(method, baseType, member, member)) { |
| 245 seen.add(method.name); | 245 seen.add(method.name); |
| 246 } | 246 } |
| 247 } | 247 } |
| 248 } | 248 } |
| 249 } | 249 } |
| 250 | 250 |
| 251 /// Checks that [element] correctly overrides its corresponding member in | 251 /// Checks that [element] correctly overrides its corresponding member in |
| 252 /// [type]. Returns `true` if an override was found, that is, if [element] has | 252 /// [type]. Returns `true` if an override was found, that is, if [element] has |
| (...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 834 if (rules.isDynamicTarget(node.leftOperand)) { | 834 if (rules.isDynamicTarget(node.leftOperand)) { |
| 835 // Dynamic invocation | 835 // Dynamic invocation |
| 836 // TODO(vsm): Move this logic to the resolver? | 836 // TODO(vsm): Move this logic to the resolver? |
| 837 if (op.type != TokenType.EQ_EQ && op.type != TokenType.BANG_EQ) { | 837 if (op.type != TokenType.EQ_EQ && op.type != TokenType.BANG_EQ) { |
| 838 _recordDynamicInvoke(node, node.leftOperand); | 838 _recordDynamicInvoke(node, node.leftOperand); |
| 839 } | 839 } |
| 840 } else { | 840 } else { |
| 841 var element = node.staticElement; | 841 var element = node.staticElement; |
| 842 // Method invocation. | 842 // Method invocation. |
| 843 if (element is MethodElement) { | 843 if (element is MethodElement) { |
| 844 var type = element.type as FunctionType; | 844 var type = element.type; |
| 845 // Analyzer should enforce number of parameter types, but check in | 845 // Analyzer should enforce number of parameter types, but check in |
| 846 // case we have erroneous input. | 846 // case we have erroneous input. |
| 847 if (type.normalParameterTypes.isNotEmpty) { | 847 if (type.normalParameterTypes.isNotEmpty) { |
| 848 checkArgument(node.rightOperand, type.normalParameterTypes[0]); | 848 checkArgument(node.rightOperand, type.normalParameterTypes[0]); |
| 849 } | 849 } |
| 850 } else { | 850 } else { |
| 851 // TODO(vsm): Assert that the analyzer found an error here? | 851 // TODO(vsm): Assert that the analyzer found an error here? |
| 852 } | 852 } |
| 853 } | 853 } |
| 854 } else { | 854 } else { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 875 } | 875 } |
| 876 | 876 |
| 877 @override | 877 @override |
| 878 void visitIndexExpression(IndexExpression node) { | 878 void visitIndexExpression(IndexExpression node) { |
| 879 var target = node.realTarget; | 879 var target = node.realTarget; |
| 880 if (rules.isDynamicTarget(target)) { | 880 if (rules.isDynamicTarget(target)) { |
| 881 _recordDynamicInvoke(node, target); | 881 _recordDynamicInvoke(node, target); |
| 882 } else { | 882 } else { |
| 883 var element = node.staticElement; | 883 var element = node.staticElement; |
| 884 if (element is MethodElement) { | 884 if (element is MethodElement) { |
| 885 var type = element.type as FunctionType; | 885 var type = element.type; |
| 886 // Analyzer should enforce number of parameter types, but check in | 886 // Analyzer should enforce number of parameter types, but check in |
| 887 // case we have erroneous input. | 887 // case we have erroneous input. |
| 888 if (type.normalParameterTypes.isNotEmpty) { | 888 if (type.normalParameterTypes.isNotEmpty) { |
| 889 checkArgument(node.index, type.normalParameterTypes[0]); | 889 checkArgument(node.index, type.normalParameterTypes[0]); |
| 890 } | 890 } |
| 891 } else { | 891 } else { |
| 892 // TODO(vsm): Assert that the analyzer found an error here? | 892 // TODO(vsm): Assert that the analyzer found an error here? |
| 893 } | 893 } |
| 894 } | 894 } |
| 895 node.visitChildren(this); | 895 node.visitChildren(this); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 var error = info.toAnalysisError(); | 999 var error = info.toAnalysisError(); |
| 1000 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) _failure = true; | 1000 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) _failure = true; |
| 1001 reporter.onError(error); | 1001 reporter.onError(error); |
| 1002 | 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 |