Chromium Code Reviews| Index: pkg/analyzer/lib/src/summary/index_unit.dart |
| diff --git a/pkg/analyzer/lib/src/summary/index_unit.dart b/pkg/analyzer/lib/src/summary/index_unit.dart |
| index 1b8f329a0a28904c7db2cde48ccfafbd9968fbc9..98258b20e57f920f30878db2990368977ec791b5 100644 |
| --- a/pkg/analyzer/lib/src/summary/index_unit.dart |
| +++ b/pkg/analyzer/lib/src/summary/index_unit.dart |
| @@ -373,14 +373,7 @@ class _IndexContributor extends GeneralizingAstVisitor { |
| @override |
| visitConstructorName(ConstructorName node) { |
| ConstructorElement element = node.staticElement; |
| - // in 'class B = A;' actually A constructors are invoked |
| - // TODO(scheglov) add support for multiple levels of redirection |
| - // TODO(scheglov) test for a loop of redirection |
| - if (element != null && |
| - element.isSynthetic && |
| - element.redirectedConstructor != null) { |
| - element = element.redirectedConstructor; |
| - } |
| + element = _getActualConstructorElement(element); |
| // record relation |
| if (node.name != null) { |
| int offset = node.period.offset; |
| @@ -549,6 +542,33 @@ class _IndexContributor extends GeneralizingAstVisitor { |
| recordSuperType(typeName, IndexRelationKind.IS_MIXED_IN_BY); |
| } |
| } |
| + |
| + /** |
| + * If the given [constructor] is a synthetic constructor created for a |
| + * [ClassTypeAlias], return the actual constructor of a [ClassDeclaration] |
| + * which is invoked. Return `null` if a redirection cycle is detected. |
| + */ |
| + ConstructorElement _getActualConstructorElement( |
| + ConstructorElement constructor) { |
| + Set<ConstructorElement> seenConstructors; |
| + // follow zero or more redirections |
| + while (constructor != null && |
| + constructor.isSynthetic && |
| + constructor.redirectedConstructor != null) { |
| + constructor = constructor.redirectedConstructor; |
| + // fail if a cycle is detected |
| + if (seenConstructors?.add(constructor) == false) { |
| + return null; |
| + } |
| + // done if no another redirection |
|
Paul Berry
2016/02/29 21:28:01
s/no another redirection/no more redirections/
|
| + if (constructor.redirectedConstructor == false) { |
|
Brian Wilkerson
2016/02/29 21:27:18
"false"?
Do we need this test anyway? Isn't it go
Paul Berry
2016/02/29 21:28:01
I think you mean `== null`, not `== false`.
But I
scheglov
2016/02/29 22:11:55
Well, yes, it is going to drop out of the while on
|
| + return constructor; |
| + } |
| + // delay the Set creation until we have a potential cycle |
| + seenConstructors ??= new Set<ConstructorElement>(); |
| + } |
| + return constructor; |
| + } |
| } |
| /** |