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.ast; | 5 library engine.ast; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'element.dart'; | 9 import 'element.dart'; |
10 import 'engine.dart' show AnalysisEngine; | 10 import 'engine.dart' show AnalysisEngine; |
(...skipping 12928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12939 } | 12939 } |
12940 if (start <= _startOffset && _endOffset <= end) { | 12940 if (start <= _startOffset && _endOffset <= end) { |
12941 _foundNode = node; | 12941 _foundNode = node; |
12942 throw new NodeLocator_NodeFoundException(); | 12942 throw new NodeLocator_NodeFoundException(); |
12943 } | 12943 } |
12944 return null; | 12944 return null; |
12945 } | 12945 } |
12946 } | 12946 } |
12947 | 12947 |
12948 /** | 12948 /** |
| 12949 * An object used to locate the [AstNode] associated with a source range. |
| 12950 * More specifically, they will return the deepest [AstNode] which completely |
| 12951 * encompasses the specified range. |
| 12952 */ |
| 12953 class NodeLocator2 extends UnifyingAstVisitor<Object> { |
| 12954 /** |
| 12955 * The inclusive start offset of the range used to identify the node. |
| 12956 */ |
| 12957 int _startOffset = 0; |
| 12958 |
| 12959 /** |
| 12960 * The inclusive end offset of the range used to identify the node. |
| 12961 */ |
| 12962 int _endOffset = 0; |
| 12963 |
| 12964 /** |
| 12965 * The found node or `null` if there is no such node. |
| 12966 */ |
| 12967 AstNode _foundNode; |
| 12968 |
| 12969 /** |
| 12970 * Initialize a newly created locator to locate the deepest [AstNode] for |
| 12971 * which `node.offset <= [startOffset]` and `[endOffset] < node.end`. |
| 12972 * |
| 12973 * If [endOffset] is not provided, then it is considered the same as the |
| 12974 * given [startOffset]. |
| 12975 */ |
| 12976 NodeLocator2(int startOffset, [int endOffset]) |
| 12977 : this._startOffset = startOffset, |
| 12978 this._endOffset = endOffset == null ? startOffset : endOffset; |
| 12979 |
| 12980 /** |
| 12981 * Search within the given AST [node] and return the node that was found, |
| 12982 * or `null` if no node was found. |
| 12983 */ |
| 12984 AstNode searchWithin(AstNode node) { |
| 12985 if (node == null) { |
| 12986 return null; |
| 12987 } |
| 12988 try { |
| 12989 node.accept(this); |
| 12990 } on NodeLocator_NodeFoundException {} catch (exception, stackTrace) { |
| 12991 AnalysisEngine.instance.logger.logInformation( |
| 12992 "Unable to locate element at offset ($_startOffset - $_endOffset)", |
| 12993 new CaughtException(exception, stackTrace)); |
| 12994 return null; |
| 12995 } |
| 12996 return _foundNode; |
| 12997 } |
| 12998 |
| 12999 @override |
| 13000 Object visitNode(AstNode node) { |
| 13001 Token beginToken = node.beginToken; |
| 13002 Token endToken = node.endToken; |
| 13003 // Don't include synthetic tokens. |
| 13004 while (endToken != beginToken) { |
| 13005 if (endToken.type == TokenType.EOF || !endToken.isSynthetic) { |
| 13006 break; |
| 13007 } |
| 13008 endToken = endToken.previous; |
| 13009 } |
| 13010 int end = endToken.end; |
| 13011 int start = node.offset; |
| 13012 if (end <= _startOffset) { |
| 13013 return null; |
| 13014 } |
| 13015 if (start > _endOffset) { |
| 13016 return null; |
| 13017 } |
| 13018 try { |
| 13019 node.visitChildren(this); |
| 13020 } on NodeLocator_NodeFoundException { |
| 13021 rethrow; |
| 13022 } catch (exception, stackTrace) { |
| 13023 // Ignore the exception and proceed in order to visit the rest of the |
| 13024 // structure. |
| 13025 AnalysisEngine.instance.logger.logInformation( |
| 13026 "Exception caught while traversing an AST structure.", |
| 13027 new CaughtException(exception, stackTrace)); |
| 13028 } |
| 13029 if (start <= _startOffset && _endOffset < end) { |
| 13030 _foundNode = node; |
| 13031 throw new NodeLocator_NodeFoundException(); |
| 13032 } |
| 13033 return null; |
| 13034 } |
| 13035 } |
| 13036 |
| 13037 /** |
12949 * An exception used by [NodeLocator] to cancel visiting after a node has been | 13038 * An exception used by [NodeLocator] to cancel visiting after a node has been |
12950 * found. | 13039 * found. |
12951 */ | 13040 */ |
12952 class NodeLocator_NodeFoundException extends RuntimeException {} | 13041 class NodeLocator_NodeFoundException extends RuntimeException {} |
12953 | 13042 |
12954 /** | 13043 /** |
12955 * An object that will replace one child node in an AST node with another node. | 13044 * An object that will replace one child node in an AST node with another node. |
12956 */ | 13045 */ |
12957 class NodeReplacer implements AstVisitor<bool> { | 13046 class NodeReplacer implements AstVisitor<bool> { |
12958 /** | 13047 /** |
(...skipping 7688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
20647 } | 20736 } |
20648 | 20737 |
20649 @override | 20738 @override |
20650 accept(AstVisitor visitor) => visitor.visitYieldStatement(this); | 20739 accept(AstVisitor visitor) => visitor.visitYieldStatement(this); |
20651 | 20740 |
20652 @override | 20741 @override |
20653 void visitChildren(AstVisitor visitor) { | 20742 void visitChildren(AstVisitor visitor) { |
20654 _safelyVisitChild(_expression, visitor); | 20743 _safelyVisitChild(_expression, visitor); |
20655 } | 20744 } |
20656 } | 20745 } |
OLD | NEW |