Chromium Code Reviews| 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 |