Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: pkg/analysis_services/lib/src/correction/statement_analyzer.dart

Issue 484733003: Import analysis_services.dart into analysis_server.dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library services.src.correction.statement_analyzer;
6
7 import 'package:analysis_services/correction/status.dart';
8 import 'package:analysis_services/src/correction/selection_analyzer.dart';
9 import 'package:analysis_services/src/correction/source_range.dart';
10 import 'package:analysis_services/src/correction/util.dart';
11 import 'package:analyzer/src/generated/ast.dart';
12 import 'package:analyzer/src/generated/element.dart';
13 import 'package:analyzer/src/generated/scanner.dart';
14 import 'package:analyzer/src/generated/source.dart';
15
16
17 /**
18 * Returns [Token]s of the given Dart source, not `null`, may be empty if no
19 * tokens or some exception happens.
20 */
21 List<Token> _getTokens(String text) {
22 try {
23 List<Token> tokens = <Token>[];
24 Scanner scanner = new Scanner(null, new CharSequenceReader(text), null);
25 Token token = scanner.tokenize();
26 while (token.type != TokenType.EOF) {
27 tokens.add(token);
28 token = token.next;
29 }
30 return tokens;
31 } catch (e) {
32 return new List<Token>(0);
33 }
34 }
35
36
37 /**
38 * Analyzer to check if a selection covers a valid set of statements of AST.
39 */
40 class StatementAnalyzer extends SelectionAnalyzer {
41 final CompilationUnit unit;
42
43 RefactoringStatus _status = new RefactoringStatus();
44
45 StatementAnalyzer(this.unit, SourceRange selection) : super(selection);
46
47 /**
48 * Returns the [RefactoringStatus] result of selection checking.
49 */
50 RefactoringStatus get status => _status;
51
52 /**
53 * Records fatal error with given message.
54 */
55 void invalidSelection(String message) {
56 invalidSelection2(message, null);
57 }
58
59 /**
60 * Records fatal error with given message and [RefactoringStatusContext].
61 */
62 void invalidSelection2(String message, RefactoringStatusContext context) {
63 _status.addFatalError(message, context);
64 reset();
65 }
66
67 @override
68 Object visitCompilationUnit(CompilationUnit node) {
69 super.visitCompilationUnit(node);
70 if (!hasSelectedNodes) {
71 return null;
72 }
73 // check that selection does not begin/end in comment
74 {
75 int selectionStart = selection.offset;
76 int selectionEnd = selection.end;
77 List<SourceRange> commentRanges = getCommentRanges(unit);
78 for (SourceRange commentRange in commentRanges) {
79 if (commentRange.contains(selectionStart)) {
80 invalidSelection("Selection begins inside a comment.");
81 }
82 if (commentRange.containsExclusive(selectionEnd)) {
83 invalidSelection("Selection ends inside a comment.");
84 }
85 }
86 }
87 // more checks
88 if (!_status.hasFatalError) {
89 _checkSelectedNodes(node);
90 }
91 return null;
92 }
93
94 @override
95 Object visitDoStatement(DoStatement node) {
96 super.visitDoStatement(node);
97 List<AstNode> selectedNodes = this.selectedNodes;
98 if (_contains(selectedNodes, node.body)) {
99 invalidSelection(
100 "Operation not applicable to a 'do' statement's body and expression.") ;
101 }
102 return null;
103 }
104
105 @override
106 Object visitForStatement(ForStatement node) {
107 super.visitForStatement(node);
108 List<AstNode> selectedNodes = this.selectedNodes;
109 bool containsInit =
110 _contains(selectedNodes, node.initialization) ||
111 _contains(selectedNodes, node.variables);
112 bool containsCondition = _contains(selectedNodes, node.condition);
113 bool containsUpdaters = _containsAny(selectedNodes, node.updaters);
114 bool containsBody = _contains(selectedNodes, node.body);
115 if (containsInit && containsCondition) {
116 invalidSelection(
117 "Operation not applicable to a 'for' statement's initializer and condi tion.");
118 } else if (containsCondition && containsUpdaters) {
119 invalidSelection(
120 "Operation not applicable to a 'for' statement's condition and updater s.");
121 } else if (containsUpdaters && containsBody) {
122 invalidSelection(
123 "Operation not applicable to a 'for' statement's updaters and body.");
124 }
125 return null;
126 }
127
128 @override
129 Object visitSwitchStatement(SwitchStatement node) {
130 super.visitSwitchStatement(node);
131 List<AstNode> selectedNodes = this.selectedNodes;
132 List<SwitchMember> switchMembers = node.members;
133 for (AstNode selectedNode in selectedNodes) {
134 if (switchMembers.contains(selectedNode)) {
135 invalidSelection(
136 "Selection must either cover whole switch statement or parts of a si ngle case block.");
137 break;
138 }
139 }
140 return null;
141 }
142
143 @override
144 Object visitTryStatement(TryStatement node) {
145 super.visitTryStatement(node);
146 AstNode firstSelectedNode = this.firstSelectedNode;
147 if (firstSelectedNode != null) {
148 if (firstSelectedNode == node.body ||
149 firstSelectedNode == node.finallyBlock) {
150 invalidSelection(
151 "Selection must either cover whole try statement or parts of try, ca tch, or finally block.");
152 } else {
153 List<CatchClause> catchClauses = node.catchClauses;
154 for (CatchClause catchClause in catchClauses) {
155 if (firstSelectedNode == catchClause ||
156 firstSelectedNode == catchClause.body ||
157 firstSelectedNode == catchClause.exceptionParameter) {
158 invalidSelection(
159 "Selection must either cover whole try statement or parts of try , catch, or finally block.");
160 }
161 }
162 }
163 }
164 return null;
165 }
166
167 @override
168 Object visitWhileStatement(WhileStatement node) {
169 super.visitWhileStatement(node);
170 List<AstNode> selectedNodes = this.selectedNodes;
171 if (_contains(selectedNodes, node.condition) &&
172 _contains(selectedNodes, node.body)) {
173 invalidSelection(
174 "Operation not applicable to a while statement's expression and body." );
175 }
176 return null;
177 }
178
179 /**
180 * Checks final selected [AstNode]s after processing [CompilationUnit].
181 */
182 void _checkSelectedNodes(CompilationUnit unit) {
183 List<AstNode> nodes = selectedNodes;
184 // some tokens before first selected node
185 {
186 AstNode firstNode = nodes[0];
187 SourceRange rangeBeforeFirstNode = rangeStartStart(selection, firstNode);
188 if (_hasTokens(rangeBeforeFirstNode)) {
189 invalidSelection2(
190 "The beginning of the selection contains characters that do not belo ng to a statement.",
191 new RefactoringStatusContext.forUnit(unit, rangeBeforeFirstNode));
192 }
193 }
194 // some tokens after last selected node
195 {
196 AstNode lastNode = nodes.last;
197 SourceRange rangeAfterLastNode = rangeEndEnd(lastNode, selection);
198 if (_hasTokens(rangeAfterLastNode)) {
199 invalidSelection2(
200 "The end of the selection contains characters that do not belong to a statement.",
201 new RefactoringStatusContext.forUnit(unit, rangeAfterLastNode));
202 }
203 }
204 }
205
206 /**
207 * Returns `true` if there are [Token]s in the given [SourceRange].
208 */
209 bool _hasTokens(SourceRange range) {
210 CompilationUnitElement unitElement = unit.element;
211 String fullText = unitElement.context.getContents(unitElement.source).data;
212 String rangeText = fullText.substring(range.offset, range.end);
213 return _getTokens(rangeText).isNotEmpty;
214 }
215
216 /**
217 * Returns `true` if [nodes] contains [node].
218 */
219 static bool _contains(List<AstNode> nodes, AstNode node) =>
220 nodes.contains(node);
221
222 /**
223 * Returns `true` if [nodes] contains one of the [otherNodes].
224 */
225 static bool _containsAny(List<AstNode> nodes, List<AstNode> otherNodes) {
226 for (AstNode otherNode in otherNodes) {
227 if (nodes.contains(otherNode)) {
228 return true;
229 }
230 }
231 return false;
232 }
233 }
OLDNEW
« no previous file with comments | « pkg/analysis_services/lib/src/correction/source_range.dart ('k') | pkg/analysis_services/lib/src/correction/strings.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698