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

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

Issue 418203002: Implement more fixes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 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 // This code was auto-generated, is not intended to be edited, and is subject to 5 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information. 6 // significant change. Please see the README file for more information.
7 7
8 library services.src.correction.util; 8 library services.src.correction.util;
9 9
10 import 'package:analysis_services/src/correction/source_range.dart'; 10 import 'package:analysis_services/src/correction/source_range.dart';
11 import 'package:analysis_services/src/correction/strings.dart'; 11 import 'package:analysis_services/src/correction/strings.dart';
12 import 'package:analyzer/src/generated/ast.dart'; 12 import 'package:analyzer/src/generated/ast.dart';
13 import 'package:analyzer/src/generated/element.dart'; 13 import 'package:analyzer/src/generated/element.dart';
14 import 'package:analyzer/src/generated/engine.dart';
14 import 'package:analyzer/src/generated/resolver.dart'; 15 import 'package:analyzer/src/generated/resolver.dart';
15 import 'package:analyzer/src/generated/source.dart'; 16 import 'package:analyzer/src/generated/source.dart';
16 17
17 18
18 String getDefaultValueCode(DartType type) { 19 String getDefaultValueCode(DartType type) {
19 if (type != null) { 20 if (type != null) {
20 String typeName = type.displayName; 21 String typeName = type.displayName;
21 if (typeName == "bool") { 22 if (typeName == "bool") {
22 return "false"; 23 return "false";
23 } 24 }
24 if (typeName == "int") { 25 if (typeName == "int") {
25 return "0"; 26 return "0";
26 } 27 }
27 if (typeName == "double") { 28 if (typeName == "double") {
28 return "0.0"; 29 return "0.0";
29 } 30 }
30 if (typeName == "String") { 31 if (typeName == "String") {
31 return "''"; 32 return "''";
32 } 33 }
33 } 34 }
34 // no better guess 35 // no better guess
35 return "null"; 36 return "null";
36 } 37 }
37 38
38 39
39 /** 40 /**
41 * @return the [ExecutableElement] of the enclosing executable [AstNode].
42 */
43 ExecutableElement getEnclosingExecutableElement(AstNode node) {
44 while (node != null) {
45 if (node is FunctionDeclaration) {
46 return node.element;
47 }
48 if (node is ConstructorDeclaration) {
49 return node.element;
50 }
51 if (node is MethodDeclaration) {
52 return node.element;
53 }
54 node = node.parent;
55 }
56 return null;
57 }
58
59
60 /**
40 * Returns [getExpressionPrecedence] for the parent of [node], 61 * Returns [getExpressionPrecedence] for the parent of [node],
41 * or `0` if the parent node is [ParenthesizedExpression]. 62 * or `0` if the parent node is [ParenthesizedExpression].
42 * 63 *
43 * The reason is that `(expr)` is always executed after `expr`. 64 * The reason is that `(expr)` is always executed after `expr`.
44 */ 65 */
45 int getExpressionParentPrecedence(AstNode node) { 66 int getExpressionParentPrecedence(AstNode node) {
46 AstNode parent = node.parent; 67 AstNode parent = node.parent;
47 if (parent is ParenthesizedExpression) { 68 if (parent is ParenthesizedExpression) {
48 return 0; 69 return 0;
49 } 70 }
(...skipping 14 matching lines...) Expand all
64 85
65 /** 86 /**
66 * Returns the namespace of the given [ImportElement]. 87 * Returns the namespace of the given [ImportElement].
67 */ 88 */
68 Map<String, Element> getImportNamespace(ImportElement imp) { 89 Map<String, Element> getImportNamespace(ImportElement imp) {
69 NamespaceBuilder builder = new NamespaceBuilder(); 90 NamespaceBuilder builder = new NamespaceBuilder();
70 Namespace namespace = builder.createImportNamespaceForDirective(imp); 91 Namespace namespace = builder.createImportNamespaceForDirective(imp);
71 return namespace.definedNames; 92 return namespace.definedNames;
72 } 93 }
73 94
95 /**
96 * If given [AstNode] is name of qualified property extraction, returns target f rom which
97 * this property is extracted. Otherwise `null`.
98 */
99 Expression getQualifiedPropertyTarget(AstNode node) {
100 AstNode parent = node.parent;
101 if (parent is PrefixedIdentifier) {
102 PrefixedIdentifier prefixed = parent;
103 if (identical(prefixed.identifier, node)) {
104 return parent.prefix;
105 }
106 }
107 if (parent is PropertyAccess) {
108 PropertyAccess access = parent;
109 if (identical(access.propertyName, node)) {
110 return access.realTarget;
111 }
112 }
113 return null;
114 }
115
116
117 /**
118 * Returns the [String] content of the given [Source].
119 */
120 String getSourceContent(AnalysisContext context, Source source) {
121 return context.getContents(source).data;
122 }
74 123
75 class CorrectionUtils { 124 class CorrectionUtils {
76 final CompilationUnit unit; 125 final CompilationUnit unit;
77 126
78 LibraryElement _library; 127 LibraryElement _library;
79 String _buffer; 128 String _buffer;
80 String _endOfLine; 129 String _endOfLine;
81 130
82 CorrectionUtils(this.unit) { 131 CorrectionUtils(this.unit) {
83 CompilationUnitElement unitElement = unit.element; 132 CompilationUnitElement unitElement = unit.element;
84 this._library = unitElement.library; 133 this._library = unitElement.library;
85 this._buffer = unitElement.context.getContents(unitElement.source).data; 134 this._buffer = unitElement.context.getContents(unitElement.source).data;
86 } 135 }
87 136
88 /** 137 /**
89 * Returns the EOL to use for this [CompilationUnit]. 138 * Returns the EOL to use for this [CompilationUnit].
90 */ 139 */
91 String get endOfLine { 140 String get endOfLine {
92 if (_endOfLine == null) { 141 if (_endOfLine == null) {
93 if (_buffer.contains("\r\n")) { 142 if (_buffer.contains("\r\n")) {
94 _endOfLine = "\r\n"; 143 _endOfLine = "\r\n";
95 } else { 144 } else {
96 _endOfLine = "\n"; 145 _endOfLine = "\n";
97 } 146 }
98 } 147 }
99 return _endOfLine; 148 return _endOfLine;
100 } 149 }
101 150
102 /** 151 /**
152 * Returns the actual type source of the given [Expression], may be `null`
153 * if can not be resolved, should be treated as the `dynamic` type.
154 */
155 String getExpressionTypeSource(Expression expression) {
156 if (expression == null) {
157 return null;
158 }
159 DartType type = expression.bestType;
160 String typeSource = getTypeSource(type);
161 if ("dynamic" == typeSource) {
Paul Berry 2014/07/25 00:28:46 Use type.isDynamic here too.
scheglov 2014/07/25 03:20:51 Done.
162 return null;
163 }
164 return typeSource;
165 }
166
167 /**
168 * Returns the indentation with the given level.
169 */
170 String getIndent(int level) => repeat(' ', level);
171
172 /**
103 * Skips whitespace characters and single EOL on the right from [index]. 173 * Skips whitespace characters and single EOL on the right from [index].
104 * 174 *
105 * If [index] the end of a statement or method, then in the most cases it is 175 * If [index] the end of a statement or method, then in the most cases it is
106 * a start of the next line. 176 * a start of the next line.
107 */ 177 */
108 int getLineContentEnd(int index) { 178 int getLineContentEnd(int index) {
109 int length = _buffer.length; 179 int length = _buffer.length;
110 // skip whitespace characters 180 // skip whitespace characters
111 while (index < length) { 181 while (index < length) {
112 int c = _buffer.codeUnitAt(index); 182 int c = _buffer.codeUnitAt(index);
(...skipping 25 matching lines...) Expand all
138 int c = _buffer.codeUnitAt(index - 1); 208 int c = _buffer.codeUnitAt(index - 1);
139 if (!isSpace(c)) { 209 if (!isSpace(c)) {
140 break; 210 break;
141 } 211 }
142 index--; 212 index--;
143 } 213 }
144 return index; 214 return index;
145 } 215 }
146 216
147 /** 217 /**
218 * Returns the whitespace prefix of the line which contains given offset.
219 */
220 String getLinePrefix(int index) {
221 int lineStart = getLineThis(index);
222 int length = _buffer.length;
223 int lineNonWhitespace = lineStart;
224 while (lineNonWhitespace < length) {
225 int c = _buffer.codeUnitAt(lineNonWhitespace);
226 if (c == 0xD || c == 0xA) {
227 break;
228 }
229 if (!isWhitespace(c)) {
230 break;
231 }
232 lineNonWhitespace++;
233 }
234 return getText2(lineStart, lineNonWhitespace - lineStart);
235 }
236
237 /**
238 * Returns the start index of the line which contains given index.
239 */
240 int getLineThis(int index) {
241 while (index > 0) {
242 int c = _buffer.codeUnitAt(index - 1);
243 if (c == 0xD || c == 0xA) {
244 break;
245 }
246 index--;
247 }
248 return index;
249 }
250
251 /**
148 * Returns a [SourceRange] that covers [range] and extends (if possible) to 252 * Returns a [SourceRange] that covers [range] and extends (if possible) to
149 * cover whole lines. 253 * cover whole lines.
150 */ 254 */
151 SourceRange getLinesRange(SourceRange range) { 255 SourceRange getLinesRange(SourceRange range) {
152 // start 256 // start
153 int startOffset = range.offset; 257 int startOffset = range.offset;
154 int startLineOffset = getLineContentStart(startOffset); 258 int startLineOffset = getLineContentStart(startOffset);
155 // end 259 // end
156 int endOffset = range.end; 260 int endOffset = range.end;
157 int afterEndLineOffset = getLineContentEnd(endOffset); 261 int afterEndLineOffset = getLineContentEnd(endOffset);
158 // range 262 // range
159 return rangeStartEnd(startLineOffset, afterEndLineOffset); 263 return rangeStartEnd(startLineOffset, afterEndLineOffset);
160 } 264 }
161 265
162 /** 266 /**
267 * Returns the line prefix consisting of spaces and tabs on the left from the given
268 * [AstNode].
269 */
270 String getNodePrefix(AstNode node) {
271 int offset = node.offset;
272 // function literal is special, it uses offset of enclosing line
273 if (node is FunctionExpression) {
274 return getLinePrefix(offset);
275 }
276 // use just prefix directly before node
277 return getPrefix(offset);
278 }
279
280 /**
163 * @return the source for the parameter with the given type and name. 281 * @return the source for the parameter with the given type and name.
164 */ 282 */
165 String getParameterSource(DartType type, String name) { 283 String getParameterSource(DartType type, String name) {
166 // no type 284 // no type
167 if (type == null || type.isDynamic) { 285 if (type == null || type.isDynamic) {
168 return name; 286 return name;
169 } 287 }
170 // function type 288 // function type
171 if (type is FunctionType) { 289 if (type is FunctionType) {
172 FunctionType functionType = type; 290 FunctionType functionType = type;
(...skipping 18 matching lines...) Expand all
191 } 309 }
192 sb.write(')'); 310 sb.write(')');
193 // done 311 // done
194 return sb.toString(); 312 return sb.toString();
195 } 313 }
196 // simple type 314 // simple type
197 return "${getTypeSource(type)} ${name}"; 315 return "${getTypeSource(type)} ${name}";
198 } 316 }
199 317
200 /** 318 /**
201 * Returns the actual type source of the given [Expression], may be `null` 319 * Returns the line prefix consisting of spaces and tabs on the left from the
202 * if can not be resolved, should be treated as the `dynamic` type. 320 * given offset.
203 */ 321 */
204 String getExpressionTypeSource(Expression expression) { 322 String getPrefix(int endIndex) {
205 if (expression == null) { 323 int startIndex = getLineContentStart(endIndex);
206 return null; 324 return _buffer.substring(startIndex, endIndex);
207 }
208 DartType type = expression.bestType;
209 String typeSource = getTypeSource(type);
210 if ("dynamic" == typeSource) {
211 return null;
212 }
213 return typeSource;
214 } 325 }
215 326
216 /** 327 /**
328 * Returns the text of the given [AstNode] in the unit.
329 */
330 String getText(AstNode node) => getText2(node.offset, node.length);
331
332 /**
333 * Returns the text of the given range in the unit.
334 */
335 String getText2(int offset, int length) =>
336 _buffer.substring(offset, offset + length);
337
338 /**
217 * Returns the source to reference [type] in this [CompilationUnit]. 339 * Returns the source to reference [type] in this [CompilationUnit].
218 */ 340 */
219 String getTypeSource(DartType type) { 341 String getTypeSource(DartType type) {
220 StringBuffer sb = new StringBuffer(); 342 StringBuffer sb = new StringBuffer();
221 // prepare element 343 // prepare element
222 Element element = type.element; 344 Element element = type.element;
223 if (element == null) { 345 if (element == null) {
224 String source = type.toString(); 346 String source = type.toString();
225 source = source.replaceAll('<dynamic>', ''); 347 source = source.replaceAll('<dynamic>', '');
226 source = source.replaceAll('<dynamic, dynamic>', ''); 348 source = source.replaceAll('<dynamic, dynamic>', '');
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 ImportElement _getImportElement(Element element) { 395 ImportElement _getImportElement(Element element) {
274 for (ImportElement imp in _library.imports) { 396 for (ImportElement imp in _library.imports) {
275 Map<String, Element> definedNames = getImportNamespace(imp); 397 Map<String, Element> definedNames = getImportNamespace(imp);
276 if (definedNames.containsValue(element)) { 398 if (definedNames.containsValue(element)) {
277 return imp; 399 return imp;
278 } 400 }
279 } 401 }
280 return null; 402 return null;
281 } 403 }
282 } 404 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698