| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 engine.resolver.error_verifier; | 5 library engine.resolver.error_verifier; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import "dart:math" as math; | 8 import "dart:math" as math; |
| 9 | 9 |
| 10 import 'java_engine.dart'; | 10 import 'java_engine.dart'; |
| (...skipping 5170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5181 return false; | 5181 return false; |
| 5182 } | 5182 } |
| 5183 | 5183 |
| 5184 /** | 5184 /** |
| 5185 * @return <code>true</code> if given [Element] has direct or indirect referen
ce to itself | 5185 * @return <code>true</code> if given [Element] has direct or indirect referen
ce to itself |
| 5186 * from anywhere except [ClassElement] or type parameter bounds. | 5186 * from anywhere except [ClassElement] or type parameter bounds. |
| 5187 */ | 5187 */ |
| 5188 bool _hasTypedefSelfReference(Element target) { | 5188 bool _hasTypedefSelfReference(Element target) { |
| 5189 Set<Element> checked = new HashSet<Element>(); | 5189 Set<Element> checked = new HashSet<Element>(); |
| 5190 List<Element> toCheck = new List<Element>(); | 5190 List<Element> toCheck = new List<Element>(); |
| 5191 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference elementVisi
tor = |
| 5192 new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(toC
heck); |
| 5191 toCheck.add(target); | 5193 toCheck.add(target); |
| 5192 bool firstIteration = true; | 5194 bool firstIteration = true; |
| 5193 while (true) { | 5195 while (true) { |
| 5194 Element current; | 5196 Element current; |
| 5195 // get next element | 5197 // get next element |
| 5196 while (true) { | 5198 while (true) { |
| 5197 // may be no more elements to check | 5199 // may be no more elements to check |
| 5198 if (toCheck.isEmpty) { | 5200 if (toCheck.isEmpty) { |
| 5199 return false; | 5201 return false; |
| 5200 } | 5202 } |
| 5201 // try to get next element | 5203 // try to get next element |
| 5202 current = toCheck.removeAt(toCheck.length - 1); | 5204 current = toCheck.removeAt(toCheck.length - 1); |
| 5203 if (target == current) { | 5205 if (target == current) { |
| 5204 if (firstIteration) { | 5206 if (firstIteration) { |
| 5205 firstIteration = false; | 5207 firstIteration = false; |
| 5206 break; | 5208 break; |
| 5207 } else { | 5209 } else { |
| 5208 return true; | 5210 return true; |
| 5209 } | 5211 } |
| 5210 } | 5212 } |
| 5211 if (current != null && !checked.contains(current)) { | 5213 if (current != null && !checked.contains(current)) { |
| 5212 break; | 5214 break; |
| 5213 } | 5215 } |
| 5214 } | 5216 } |
| 5215 // check current element | 5217 // check current element |
| 5216 current.accept(new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelf
Reference(target, toCheck)); | 5218 current.accept(elementVisitor); |
| 5217 checked.add(current); | 5219 checked.add(current); |
| 5218 } | 5220 } |
| 5219 } | 5221 } |
| 5220 | 5222 |
| 5221 bool _isFunctionType(DartType type) { | 5223 bool _isFunctionType(DartType type) { |
| 5222 if (type.isDynamic || type.isBottom) { | 5224 if (type.isDynamic || type.isBottom) { |
| 5223 return true; | 5225 return true; |
| 5224 } else if (type is FunctionType || type.isDartCoreFunction) { | 5226 } else if (type is FunctionType || type.isDartCoreFunction) { |
| 5225 return true; | 5227 return true; |
| 5226 } else if (type is InterfaceType) { | 5228 } else if (type is InterfaceType) { |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5421 if (_safeCheckForRecursiveInterfaceInheritance(mixinType.element, path)) { | 5423 if (_safeCheckForRecursiveInterfaceInheritance(mixinType.element, path)) { |
| 5422 return true; | 5424 return true; |
| 5423 } | 5425 } |
| 5424 } | 5426 } |
| 5425 path.removeAt(path.length - 1); | 5427 path.removeAt(path.length - 1); |
| 5426 return false; | 5428 return false; |
| 5427 } | 5429 } |
| 5428 } | 5430 } |
| 5429 | 5431 |
| 5430 class GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference extends G
eneralizingElementVisitor<Object> { | 5432 class GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference extends G
eneralizingElementVisitor<Object> { |
| 5431 Element target; | |
| 5432 | |
| 5433 List<Element> toCheck; | 5433 List<Element> toCheck; |
| 5434 | 5434 |
| 5435 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(this.target,
this.toCheck) : super(); | 5435 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference( |
| 5436 | 5436 this.toCheck) : super(); |
| 5437 bool _inClass = false; | |
| 5438 | 5437 |
| 5439 @override | 5438 @override |
| 5440 Object visitClassElement(ClassElement element) { | 5439 Object visitClassElement(ClassElement element) { |
| 5441 _addTypeToCheck(element.supertype); | 5440 // Typedefs are allowed to reference themselves via classes. |
| 5442 for (InterfaceType mixin in element.mixins) { | 5441 return null; |
| 5443 _addTypeToCheck(mixin); | |
| 5444 } | |
| 5445 _inClass = !element.isTypedef; | |
| 5446 try { | |
| 5447 return super.visitClassElement(element); | |
| 5448 } finally { | |
| 5449 _inClass = false; | |
| 5450 } | |
| 5451 } | 5442 } |
| 5452 | 5443 |
| 5453 @override | 5444 @override |
| 5454 Object visitExecutableElement(ExecutableElement element) { | |
| 5455 if (element.isSynthetic) { | |
| 5456 return null; | |
| 5457 } | |
| 5458 _addTypeToCheck(element.returnType); | |
| 5459 return super.visitExecutableElement(element); | |
| 5460 } | |
| 5461 | |
| 5462 @override | |
| 5463 Object visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { | 5445 Object visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { |
| 5464 _addTypeToCheck(element.returnType); | 5446 _addTypeToCheck(element.returnType); |
| 5465 return super.visitFunctionTypeAliasElement(element); | 5447 return super.visitFunctionTypeAliasElement(element); |
| 5466 } | 5448 } |
| 5467 | 5449 |
| 5468 @override | 5450 @override |
| 5469 Object visitParameterElement(ParameterElement element) { | 5451 Object visitParameterElement(ParameterElement element) { |
| 5470 _addTypeToCheck(element.type); | 5452 _addTypeToCheck(element.type); |
| 5471 return super.visitParameterElement(element); | 5453 return super.visitParameterElement(element); |
| 5472 } | 5454 } |
| 5473 | 5455 |
| 5474 @override | 5456 @override |
| 5475 Object visitTypeParameterElement(TypeParameterElement element) { | 5457 Object visitTypeParameterElement(TypeParameterElement element) { |
| 5476 _addTypeToCheck(element.bound); | 5458 _addTypeToCheck(element.bound); |
| 5477 return super.visitTypeParameterElement(element); | 5459 return super.visitTypeParameterElement(element); |
| 5478 } | 5460 } |
| 5479 | 5461 |
| 5480 @override | |
| 5481 Object visitVariableElement(VariableElement element) { | |
| 5482 _addTypeToCheck(element.type); | |
| 5483 return super.visitVariableElement(element); | |
| 5484 } | |
| 5485 | |
| 5486 void _addTypeToCheck(DartType type) { | 5462 void _addTypeToCheck(DartType type) { |
| 5487 if (type == null) { | 5463 if (type == null) { |
| 5488 return; | 5464 return; |
| 5489 } | 5465 } |
| 5490 Element element = type.element; | |
| 5491 // it is OK to reference target from class | |
| 5492 if (_inClass && target == element) { | |
| 5493 return; | |
| 5494 } | |
| 5495 // schedule for checking | 5466 // schedule for checking |
| 5496 toCheck.add(element); | 5467 toCheck.add(type.element); |
| 5497 // type arguments | 5468 // type arguments |
| 5498 if (type is InterfaceType) { | 5469 if (type is InterfaceType) { |
| 5499 InterfaceType interfaceType = type; | 5470 InterfaceType interfaceType = type; |
| 5500 for (DartType typeArgument in interfaceType.typeArguments) { | 5471 for (DartType typeArgument in interfaceType.typeArguments) { |
| 5501 _addTypeToCheck(typeArgument); | 5472 _addTypeToCheck(typeArgument); |
| 5502 } | 5473 } |
| 5503 } | 5474 } |
| 5504 } | 5475 } |
| 5505 } | 5476 } |
| OLD | NEW |