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 if (type.isDynamic) { |
| 161 return null; |
| 162 } |
| 163 return getTypeSource(type); |
| 164 } |
| 165 |
| 166 /** |
| 167 * Returns the indentation with the given level. |
| 168 */ |
| 169 String getIndent(int level) => repeat(' ', level); |
| 170 |
| 171 /** |
103 * Skips whitespace characters and single EOL on the right from [index]. | 172 * Skips whitespace characters and single EOL on the right from [index]. |
104 * | 173 * |
105 * If [index] the end of a statement or method, then in the most cases it is | 174 * If [index] the end of a statement or method, then in the most cases it is |
106 * a start of the next line. | 175 * a start of the next line. |
107 */ | 176 */ |
108 int getLineContentEnd(int index) { | 177 int getLineContentEnd(int index) { |
109 int length = _buffer.length; | 178 int length = _buffer.length; |
110 // skip whitespace characters | 179 // skip whitespace characters |
111 while (index < length) { | 180 while (index < length) { |
112 int c = _buffer.codeUnitAt(index); | 181 int c = _buffer.codeUnitAt(index); |
(...skipping 25 matching lines...) Expand all Loading... |
138 int c = _buffer.codeUnitAt(index - 1); | 207 int c = _buffer.codeUnitAt(index - 1); |
139 if (!isSpace(c)) { | 208 if (!isSpace(c)) { |
140 break; | 209 break; |
141 } | 210 } |
142 index--; | 211 index--; |
143 } | 212 } |
144 return index; | 213 return index; |
145 } | 214 } |
146 | 215 |
147 /** | 216 /** |
| 217 * Returns the whitespace prefix of the line which contains given offset. |
| 218 */ |
| 219 String getLinePrefix(int index) { |
| 220 int lineStart = getLineThis(index); |
| 221 int length = _buffer.length; |
| 222 int lineNonWhitespace = lineStart; |
| 223 while (lineNonWhitespace < length) { |
| 224 int c = _buffer.codeUnitAt(lineNonWhitespace); |
| 225 if (c == 0xD || c == 0xA) { |
| 226 break; |
| 227 } |
| 228 if (!isWhitespace(c)) { |
| 229 break; |
| 230 } |
| 231 lineNonWhitespace++; |
| 232 } |
| 233 return getText2(lineStart, lineNonWhitespace - lineStart); |
| 234 } |
| 235 |
| 236 /** |
| 237 * Returns the start index of the line which contains given index. |
| 238 */ |
| 239 int getLineThis(int index) { |
| 240 while (index > 0) { |
| 241 int c = _buffer.codeUnitAt(index - 1); |
| 242 if (c == 0xD || c == 0xA) { |
| 243 break; |
| 244 } |
| 245 index--; |
| 246 } |
| 247 return index; |
| 248 } |
| 249 |
| 250 /** |
148 * Returns a [SourceRange] that covers [range] and extends (if possible) to | 251 * Returns a [SourceRange] that covers [range] and extends (if possible) to |
149 * cover whole lines. | 252 * cover whole lines. |
150 */ | 253 */ |
151 SourceRange getLinesRange(SourceRange range) { | 254 SourceRange getLinesRange(SourceRange range) { |
152 // start | 255 // start |
153 int startOffset = range.offset; | 256 int startOffset = range.offset; |
154 int startLineOffset = getLineContentStart(startOffset); | 257 int startLineOffset = getLineContentStart(startOffset); |
155 // end | 258 // end |
156 int endOffset = range.end; | 259 int endOffset = range.end; |
157 int afterEndLineOffset = getLineContentEnd(endOffset); | 260 int afterEndLineOffset = getLineContentEnd(endOffset); |
158 // range | 261 // range |
159 return rangeStartEnd(startLineOffset, afterEndLineOffset); | 262 return rangeStartEnd(startLineOffset, afterEndLineOffset); |
160 } | 263 } |
161 | 264 |
162 /** | 265 /** |
| 266 * Returns the line prefix consisting of spaces and tabs on the left from the
given |
| 267 * [AstNode]. |
| 268 */ |
| 269 String getNodePrefix(AstNode node) { |
| 270 int offset = node.offset; |
| 271 // function literal is special, it uses offset of enclosing line |
| 272 if (node is FunctionExpression) { |
| 273 return getLinePrefix(offset); |
| 274 } |
| 275 // use just prefix directly before node |
| 276 return getPrefix(offset); |
| 277 } |
| 278 |
| 279 /** |
163 * @return the source for the parameter with the given type and name. | 280 * @return the source for the parameter with the given type and name. |
164 */ | 281 */ |
165 String getParameterSource(DartType type, String name) { | 282 String getParameterSource(DartType type, String name) { |
166 // no type | 283 // no type |
167 if (type == null || type.isDynamic) { | 284 if (type == null || type.isDynamic) { |
168 return name; | 285 return name; |
169 } | 286 } |
170 // function type | 287 // function type |
171 if (type is FunctionType) { | 288 if (type is FunctionType) { |
172 FunctionType functionType = type; | 289 FunctionType functionType = type; |
(...skipping 18 matching lines...) Expand all Loading... |
191 } | 308 } |
192 sb.write(')'); | 309 sb.write(')'); |
193 // done | 310 // done |
194 return sb.toString(); | 311 return sb.toString(); |
195 } | 312 } |
196 // simple type | 313 // simple type |
197 return "${getTypeSource(type)} ${name}"; | 314 return "${getTypeSource(type)} ${name}"; |
198 } | 315 } |
199 | 316 |
200 /** | 317 /** |
201 * Returns the actual type source of the given [Expression], may be `null` | 318 * 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. | 319 * given offset. |
203 */ | 320 */ |
204 String getExpressionTypeSource(Expression expression) { | 321 String getPrefix(int endIndex) { |
205 if (expression == null) { | 322 int startIndex = getLineContentStart(endIndex); |
206 return null; | 323 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 } | 324 } |
215 | 325 |
216 /** | 326 /** |
| 327 * Returns the text of the given [AstNode] in the unit. |
| 328 */ |
| 329 String getText(AstNode node) => getText2(node.offset, node.length); |
| 330 |
| 331 /** |
| 332 * Returns the text of the given range in the unit. |
| 333 */ |
| 334 String getText2(int offset, int length) => |
| 335 _buffer.substring(offset, offset + length); |
| 336 |
| 337 /** |
217 * Returns the source to reference [type] in this [CompilationUnit]. | 338 * Returns the source to reference [type] in this [CompilationUnit]. |
218 */ | 339 */ |
219 String getTypeSource(DartType type) { | 340 String getTypeSource(DartType type) { |
220 StringBuffer sb = new StringBuffer(); | 341 StringBuffer sb = new StringBuffer(); |
221 // prepare element | 342 // prepare element |
222 Element element = type.element; | 343 Element element = type.element; |
223 if (element == null) { | 344 if (element == null) { |
224 String source = type.toString(); | 345 String source = type.toString(); |
225 source = source.replaceAll('<dynamic>', ''); | 346 source = source.replaceAll('<dynamic>', ''); |
226 source = source.replaceAll('<dynamic, dynamic>', ''); | 347 source = source.replaceAll('<dynamic, dynamic>', ''); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 ImportElement _getImportElement(Element element) { | 394 ImportElement _getImportElement(Element element) { |
274 for (ImportElement imp in _library.imports) { | 395 for (ImportElement imp in _library.imports) { |
275 Map<String, Element> definedNames = getImportNamespace(imp); | 396 Map<String, Element> definedNames = getImportNamespace(imp); |
276 if (definedNames.containsValue(element)) { | 397 if (definedNames.containsValue(element)) { |
277 return imp; | 398 return imp; |
278 } | 399 } |
279 } | 400 } |
280 return null; | 401 return null; |
281 } | 402 } |
282 } | 403 } |
OLD | NEW |