| Index: pkg/fasta/lib/src/kernel/redirecting_factory_body.dart
|
| diff --git a/pkg/fasta/lib/src/kernel/redirecting_factory_body.dart b/pkg/fasta/lib/src/kernel/redirecting_factory_body.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ada143602d77deff9a5fae07d68525d1e942fdb1
|
| --- /dev/null
|
| +++ b/pkg/fasta/lib/src/kernel/redirecting_factory_body.dart
|
| @@ -0,0 +1,45 @@
|
| +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +library fasta.redirecting_factory_body;
|
| +
|
| +import 'package:kernel/ast.dart' show
|
| + InvalidStatement,
|
| + Member,
|
| + Procedure;
|
| +
|
| +class RedirectingFactoryBody extends InvalidStatement {
|
| + final Member target;
|
| +
|
| + RedirectingFactoryBody(this.target);
|
| +}
|
| +
|
| +bool isRedirectingFactory(Member member) {
|
| + return member is Procedure &&
|
| + member.function.body is RedirectingFactoryBody;
|
| +}
|
| +
|
| +Member getImmediateRedirectionTarget(Member member) {
|
| + if (isRedirectingFactory(member)) {
|
| + Procedure procedure = member;
|
| + RedirectingFactoryBody body = procedure.function.body;
|
| + return body.target;
|
| + } else {
|
| + return null;
|
| + }
|
| +}
|
| +
|
| +Member getRedirectionTarget(Procedure member) {
|
| + // We use the [tortoise and hare algorithm]
|
| + // (https://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare) to
|
| + // handle cycles.
|
| + Member tortoise = member;
|
| + Member hare = getImmediateRedirectionTarget(member);
|
| + while (tortoise != hare) {
|
| + if (!isRedirectingFactory(tortoise)) return tortoise;
|
| + tortoise = getImmediateRedirectionTarget(tortoise);
|
| + hare = getImmediateRedirectionTarget(getImmediateRedirectionTarget(hare));
|
| + }
|
| + return null;
|
| +}
|
|
|