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 // 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |