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

Side by Side Diff: pkg/analysis_server/lib/src/services/correction/util.dart

Issue 574573002: Add SourceFileEdit.time field. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: tweak Created 6 years, 3 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
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 services.src.correction.util; 5 library services.src.correction.util;
6 6
7 import 'dart:math'; 7 import 'dart:math';
8 8
9 import 'package:analysis_server/src/protocol.dart' show SourceEdit; 9 import 'package:analysis_server/src/protocol.dart' show SourceChange,
10 SourceEdit;
10 import 'package:analysis_server/src/services/correction/source_range.dart'; 11 import 'package:analysis_server/src/services/correction/source_range.dart';
11 import 'package:analysis_server/src/services/correction/strings.dart'; 12 import 'package:analysis_server/src/services/correction/strings.dart';
12 import 'package:analyzer/src/generated/ast.dart'; 13 import 'package:analyzer/src/generated/ast.dart';
13 import 'package:analyzer/src/generated/element.dart'; 14 import 'package:analyzer/src/generated/element.dart';
14 import 'package:analyzer/src/generated/engine.dart'; 15 import 'package:analyzer/src/generated/engine.dart';
15 import 'package:analyzer/src/generated/resolver.dart'; 16 import 'package:analyzer/src/generated/resolver.dart';
16 import 'package:analyzer/src/generated/scanner.dart'; 17 import 'package:analyzer/src/generated/scanner.dart';
17 import 'package:analyzer/src/generated/source.dart'; 18 import 'package:analyzer/src/generated/source.dart';
18 19
19 20
21 void addElementSourceChange(SourceChange change, Element element,
22 SourceEdit edit) {
23 AnalysisContext context = element.context;
24 Source source = element.source;
25 addSourceChange(change, context, source, edit);
26 }
27
28
29 void addSourceChange(SourceChange change, AnalysisContext context,
30 Source source, SourceEdit edit) {
31 String file = source.fullName;
32 int fileStamp = context.getModificationStamp(source);
33 change.addEdit(file, fileStamp, edit);
34 }
35
36
20 /** 37 /**
21 * @return <code>true</code> if given [List]s are identical at given position. 38 * @return <code>true</code> if given [List]s are identical at given position.
22 */ 39 */
23 bool allListsIdentical(List<List> lists, int position) { 40 bool allListsIdentical(List<List> lists, int position) {
24 Object element = lists[0][position]; 41 Object element = lists[0][position];
25 for (List list in lists) { 42 for (List list in lists) {
26 if (list[position] != element) { 43 if (list[position] != element) {
27 return false; 44 return false;
28 } 45 }
29 } 46 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 90
74 91
75 /** 92 /**
76 * Return the name of the [Element] kind. 93 * Return the name of the [Element] kind.
77 */ 94 */
78 String getElementKindName(Element element) { 95 String getElementKindName(Element element) {
79 return element.kind.displayName; 96 return element.kind.displayName;
80 } 97 }
81 98
82 99
100
83 /** 101 /**
84 * Returns the name to display in the UI for the given [Element]. 102 * Returns the name to display in the UI for the given [Element].
85 */ 103 */
86 String getElementQualifiedName(Element element) { 104 String getElementQualifiedName(Element element) {
87 ElementKind kind = element.kind; 105 ElementKind kind = element.kind;
88 if (kind == ElementKind.FIELD || kind == ElementKind.METHOD) { 106 if (kind == ElementKind.FIELD || kind == ElementKind.METHOD) {
89 return '${element.enclosingElement.displayName}.${element.displayName}'; 107 return '${element.enclosingElement.displayName}.${element.displayName}';
90 } else { 108 } else {
91 return element.displayName; 109 return element.displayName;
92 } 110 }
93 } 111 }
94 112
95
96 /** 113 /**
97 * If the given [AstNode] is in a [ClassDeclaration], returns the 114 * If the given [AstNode] is in a [ClassDeclaration], returns the
98 * [ClassElement]. Otherwise returns `null`. 115 * [ClassElement]. Otherwise returns `null`.
99 */ 116 */
100 ClassElement getEnclosingClassElement(AstNode node) { 117 ClassElement getEnclosingClassElement(AstNode node) {
101 ClassDeclaration enclosingClassNode = 118 ClassDeclaration enclosingClassNode =
102 node.getAncestor((node) => node is ClassDeclaration); 119 node.getAncestor((node) => node is ClassDeclaration);
103 if (enclosingClassNode != null) { 120 if (enclosingClassNode != null) {
104 return enclosingClassNode.element; 121 return enclosingClassNode.element;
105 } 122 }
106 return null; 123 return null;
107 } 124 }
108 125
109 126
110
111 /** 127 /**
112 * Returns a class or an unit member enclosing the given [node]. 128 * Returns a class or an unit member enclosing the given [node].
113 */ 129 */
114 AstNode getEnclosingClassOrUnitMember(AstNode node) { 130 AstNode getEnclosingClassOrUnitMember(AstNode node) {
115 AstNode member = node; 131 AstNode member = node;
116 while (node != null) { 132 while (node != null) {
117 if (node is ClassDeclaration) { 133 if (node is ClassDeclaration) {
118 return member; 134 return member;
119 } 135 }
120 if (node is CompilationUnit) { 136 if (node is CompilationUnit) {
121 return member; 137 return member;
122 } 138 }
123 member = node; 139 member = node;
124 node = node.parent; 140 node = node.parent;
125 } 141 }
126 return null; 142 return null;
127 } 143 }
128 144
145
129 /** 146 /**
130 * @return the [ExecutableElement] of the enclosing executable [AstNode]. 147 * @return the [ExecutableElement] of the enclosing executable [AstNode].
131 */ 148 */
132 ExecutableElement getEnclosingExecutableElement(AstNode node) { 149 ExecutableElement getEnclosingExecutableElement(AstNode node) {
133 while (node != null) { 150 while (node != null) {
134 if (node is FunctionDeclaration) { 151 if (node is FunctionDeclaration) {
135 return node.element; 152 return node.element;
136 } 153 }
137 if (node is ConstructorDeclaration) { 154 if (node is ConstructorDeclaration) {
138 return node.element; 155 return node.element;
(...skipping 20 matching lines...) Expand all
159 } 176 }
160 if (node is MethodDeclaration) { 177 if (node is MethodDeclaration) {
161 return node; 178 return node;
162 } 179 }
163 node = node.parent; 180 node = node.parent;
164 } 181 }
165 return null; 182 return null;
166 } 183 }
167 184
168 185
186
169 /** 187 /**
170 * Returns [getExpressionPrecedence] for the parent of [node], 188 * Returns [getExpressionPrecedence] for the parent of [node],
171 * or `0` if the parent node is [ParenthesizedExpression]. 189 * or `0` if the parent node is [ParenthesizedExpression].
172 * 190 *
173 * The reason is that `(expr)` is always executed after `expr`. 191 * The reason is that `(expr)` is always executed after `expr`.
174 */ 192 */
175 int getExpressionParentPrecedence(AstNode node) { 193 int getExpressionParentPrecedence(AstNode node) {
176 AstNode parent = node.parent; 194 AstNode parent = node.parent;
177 if (parent is ParenthesizedExpression) { 195 if (parent is ParenthesizedExpression) {
178 return 0; 196 return 0;
179 } 197 }
180 return getExpressionPrecedence(parent); 198 return getExpressionPrecedence(parent);
181 } 199 }
182 200
183 201
184 /** 202 /**
185 * Returns the precedence of [node] it is an [Expression], negative otherwise. 203 * Returns the precedence of [node] it is an [Expression], negative otherwise.
186 */ 204 */
187 int getExpressionPrecedence(AstNode node) { 205 int getExpressionPrecedence(AstNode node) {
188 if (node is Expression) { 206 if (node is Expression) {
189 return node.precedence; 207 return node.precedence;
190 } 208 }
191 return -1000; 209 return -1000;
192 } 210 }
193 211
194 212
195
196 /** 213 /**
197 * Returns the namespace of the given [ImportElement]. 214 * Returns the namespace of the given [ImportElement].
198 */ 215 */
199 Map<String, Element> getImportNamespace(ImportElement imp) { 216 Map<String, Element> getImportNamespace(ImportElement imp) {
200 NamespaceBuilder builder = new NamespaceBuilder(); 217 NamespaceBuilder builder = new NamespaceBuilder();
201 Namespace namespace = builder.createImportNamespaceForDirective(imp); 218 Namespace namespace = builder.createImportNamespaceForDirective(imp);
202 return namespace.definedNames; 219 return namespace.definedNames;
203 } 220 }
204 221
205 222
206 /** 223 /**
207 * Returns the line prefix from the given source, i.e. basically just a 224 * Returns the line prefix from the given source, i.e. basically just a
208 * whitespace prefix of the given [String]. 225 * whitespace prefix of the given [String].
209 */ 226 */
210 String getLinePrefix(String line) { 227 String getLinePrefix(String line) {
211 int index = 0; 228 int index = 0;
212 while (index < line.length) { 229 while (index < line.length) {
213 int c = line.codeUnitAt(index); 230 int c = line.codeUnitAt(index);
214 if (!isWhitespace(c)) { 231 if (!isWhitespace(c)) {
215 break; 232 break;
216 } 233 }
217 index++; 234 index++;
218 } 235 }
219 return line.substring(0, index); 236 return line.substring(0, index);
220 } 237 }
221 238
222
223 /** 239 /**
224 * @return the [LocalVariableElement] or [ParameterElement] if given 240 * @return the [LocalVariableElement] or [ParameterElement] if given
225 * [SimpleIdentifier] is the reference to local variable or parameter, o r 241 * [SimpleIdentifier] is the reference to local variable or parameter, o r
226 * <code>null</code> in the other case. 242 * <code>null</code> in the other case.
227 */ 243 */
228 VariableElement getLocalOrParameterVariableElement(SimpleIdentifier node) { 244 VariableElement getLocalOrParameterVariableElement(SimpleIdentifier node) {
229 Element element = node.staticElement; 245 Element element = node.staticElement;
230 if (element is LocalVariableElement) { 246 if (element is LocalVariableElement) {
231 return element; 247 return element;
232 } 248 }
233 if (element is ParameterElement) { 249 if (element is ParameterElement) {
234 return element; 250 return element;
235 } 251 }
236 return null; 252 return null;
237 } 253 }
238 254
239
240 /** 255 /**
241 * @return the [LocalVariableElement] if given [SimpleIdentifier] is the referen ce to 256 * @return the [LocalVariableElement] if given [SimpleIdentifier] is the referen ce to
242 * local variable, or <code>null</code> in the other case. 257 * local variable, or <code>null</code> in the other case.
243 */ 258 */
244 LocalVariableElement getLocalVariableElement(SimpleIdentifier node) { 259 LocalVariableElement getLocalVariableElement(SimpleIdentifier node) {
245 Element element = node.staticElement; 260 Element element = node.staticElement;
246 if (element is LocalVariableElement) { 261 if (element is LocalVariableElement) {
247 return element; 262 return element;
248 } 263 }
249 return null; 264 return null;
250 } 265 }
251 266
267
252 /** 268 /**
253 * @return the nearest common ancestor [AstNode] of the given [AstNode]s. 269 * @return the nearest common ancestor [AstNode] of the given [AstNode]s.
254 */ 270 */
255 AstNode getNearestCommonAncestor(List<AstNode> nodes) { 271 AstNode getNearestCommonAncestor(List<AstNode> nodes) {
256 // may be no nodes 272 // may be no nodes
257 if (nodes.isEmpty) { 273 if (nodes.isEmpty) {
258 return null; 274 return null;
259 } 275 }
260 // prepare parents 276 // prepare parents
261 List<List<AstNode>> parents = []; 277 List<List<AstNode>> parents = [];
262 for (AstNode node in nodes) { 278 for (AstNode node in nodes) {
263 parents.add(getParents(node)); 279 parents.add(getParents(node));
264 } 280 }
265 // find min length 281 // find min length
266 int minLength = 1 << 20; 282 int minLength = 1 << 20;
267 for (List<AstNode> parentList in parents) { 283 for (List<AstNode> parentList in parents) {
268 minLength = min(minLength, parentList.length); 284 minLength = min(minLength, parentList.length);
269 } 285 }
270 // find deepest parent 286 // find deepest parent
271 int i = 0; 287 int i = 0;
272 for ( ; i < minLength; i++) { 288 for ( ; i < minLength; i++) {
273 if (!allListsIdentical(parents, i)) { 289 if (!allListsIdentical(parents, i)) {
274 break; 290 break;
275 } 291 }
276 } 292 }
277 return parents[0][i - 1]; 293 return parents[0][i - 1];
278 } 294 }
279 295
296
280 /** 297 /**
281 * Returns the [Expression] qualifier if given node is the name part of a 298 * Returns the [Expression] qualifier if given node is the name part of a
282 * [PropertyAccess] or a [PrefixedIdentifier]. Maybe `null`. 299 * [PropertyAccess] or a [PrefixedIdentifier]. Maybe `null`.
283 */ 300 */
284 Expression getNodeQualifier(SimpleIdentifier node) { 301 Expression getNodeQualifier(SimpleIdentifier node) {
285 AstNode parent = node.parent; 302 AstNode parent = node.parent;
286 if (parent is PropertyAccess) { 303 if (parent is PropertyAccess) {
287 PropertyAccess propertyAccess = parent; 304 PropertyAccess propertyAccess = parent;
288 if (identical(propertyAccess.propertyName, node)) { 305 if (identical(propertyAccess.propertyName, node)) {
289 return propertyAccess.target; 306 return propertyAccess.target;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 } 405 }
389 406
390 407
391 /** 408 /**
392 * Returns the [String] content of the given [Source]. 409 * Returns the [String] content of the given [Source].
393 */ 410 */
394 String getSourceContent(AnalysisContext context, Source source) { 411 String getSourceContent(AnalysisContext context, Source source) {
395 return context.getContents(source).data; 412 return context.getContents(source).data;
396 } 413 }
397 414
398
399 /** 415 /**
400 * Returns the given [Statement] if not a [Block], or all the children 416 * Returns the given [Statement] if not a [Block], or all the children
401 * [Statement]s if a [Block]. 417 * [Statement]s if a [Block].
402 */ 418 */
403 List<Statement> getStatements(Statement statement) { 419 List<Statement> getStatements(Statement statement) {
404 if (statement is Block) { 420 if (statement is Block) {
405 return statement.statements; 421 return statement.statements;
406 } 422 }
407 return [statement]; 423 return [statement];
408 } 424 }
409 425
410 426
411 /** 427 /**
412 * Checks if the given [Element]'s display name equals to the given name. 428 * Checks if the given [Element]'s display name equals to the given name.
413 */ 429 */
414 bool hasDisplayName(Element element, String name) { 430 bool hasDisplayName(Element element, String name) {
415 if (element == null) { 431 if (element == null) {
416 return false; 432 return false;
417 } 433 }
418 return element.displayName == name; 434 return element.displayName == name;
419 } 435 }
420 436
437
421 /** 438 /**
422 * Checks if the given [PropertyAccessorElement] is an accessor of a 439 * Checks if the given [PropertyAccessorElement] is an accessor of a
423 * [FieldElement]. 440 * [FieldElement].
424 */ 441 */
425 bool isFieldAccessorElement(PropertyAccessorElement accessor) { 442 bool isFieldAccessorElement(PropertyAccessorElement accessor) {
426 return accessor != null && accessor.variable is FieldElement; 443 return accessor != null && accessor.variable is FieldElement;
427 } 444 }
428 445
429 446
430 /** 447 /**
(...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after
1382 1399
1383 @override 1400 @override
1384 Object visitExpression(Expression node) { 1401 Object visitExpression(Expression node) {
1385 if (node is BinaryExpression && node.operator.type == groupOperatorType) { 1402 if (node is BinaryExpression && node.operator.type == groupOperatorType) {
1386 return super.visitNode(node); 1403 return super.visitNode(node);
1387 } 1404 }
1388 operands.add(node); 1405 operands.add(node);
1389 return null; 1406 return null;
1390 } 1407 }
1391 } 1408 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698