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.fix; | 8 library services.src.correction.fix; |
| 9 | 9 |
| 10 import 'package:analysis_services/correction/change.dart'; | 10 import 'package:analysis_services/correction/change.dart'; |
| 11 import 'package:analysis_services/correction/fix.dart'; | 11 import 'package:analysis_services/correction/fix.dart'; |
| 12 import 'package:analysis_services/search/search_engine.dart'; | 12 import 'package:analysis_services/search/search_engine.dart'; |
| 13 import 'package:analysis_services/src/correction/name_suggestion.dart'; | 13 import 'package:analysis_services/src/correction/name_suggestion.dart'; |
| 14 import 'package:analysis_services/src/correction/source_buffer.dart'; | 14 import 'package:analysis_services/src/correction/source_buffer.dart'; |
| 15 import 'package:analysis_services/src/correction/source_range.dart' as rf; | 15 import 'package:analysis_services/src/correction/source_range.dart' as rf; |
| 16 import 'package:analysis_services/src/correction/strings.dart'; | |
| 16 import 'package:analysis_services/src/correction/util.dart'; | 17 import 'package:analysis_services/src/correction/util.dart'; |
| 17 import 'package:analyzer/src/generated/ast.dart'; | 18 import 'package:analyzer/src/generated/ast.dart'; |
| 18 import 'package:analyzer/src/generated/element.dart'; | 19 import 'package:analyzer/src/generated/element.dart'; |
| 19 import 'package:analyzer/src/generated/error.dart'; | 20 import 'package:analyzer/src/generated/error.dart'; |
| 20 import 'package:analyzer/src/generated/java_core.dart'; | 21 import 'package:analyzer/src/generated/java_core.dart'; |
| 21 import 'package:analyzer/src/generated/parser.dart'; | 22 import 'package:analyzer/src/generated/parser.dart'; |
| 23 import 'package:analyzer/src/generated/scanner.dart'; | |
| 22 import 'package:analyzer/src/generated/source.dart'; | 24 import 'package:analyzer/src/generated/source.dart'; |
| 23 import 'package:analyzer/src/generated/utilities_dart.dart'; | 25 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 24 | 26 |
| 25 | 27 |
| 26 /** | 28 /** |
| 27 * The computer for Dart fixes. | 29 * The computer for Dart fixes. |
| 28 */ | 30 */ |
| 29 class FixProcessor { | 31 class FixProcessor { |
| 30 final SearchEngine searchEngine; | 32 final SearchEngine searchEngine; |
| 33 final Source source; | |
| 31 final String file; | 34 final String file; |
| 32 final CompilationUnit unit; | 35 final CompilationUnit unit; |
| 33 final AnalysisError error; | 36 final AnalysisError error; |
| 37 CompilationUnitElement unitElement; | |
| 38 LibraryElement unitLibraryElement; | |
| 34 | 39 |
| 35 final List<Edit> edits = <Edit>[]; | 40 final List<Edit> edits = <Edit>[]; |
| 36 final Map<String, LinkedPositionGroup> linkedPositionGroups = <String, | 41 final Map<String, LinkedPositionGroup> linkedPositionGroups = <String, |
| 37 LinkedPositionGroup>{}; | 42 LinkedPositionGroup>{}; |
| 43 Position endPosition = null; | |
| 38 final List<Fix> fixes = <Fix>[]; | 44 final List<Fix> fixes = <Fix>[]; |
| 39 | 45 |
| 40 CorrectionUtils utils; | 46 CorrectionUtils utils; |
| 41 int errorOffset; | 47 int errorOffset; |
| 42 int errorLength; | 48 int errorLength; |
| 43 int errorEnd; | 49 int errorEnd; |
| 44 AstNode node; | 50 AstNode node; |
| 45 AstNode coveredNode; | 51 AstNode coveredNode; |
| 46 | 52 |
| 47 | 53 |
| 48 FixProcessor(this.searchEngine, this.file, this.unit, this.error); | 54 FixProcessor(this.searchEngine, this.source, this.file, this.unit, this.error) |
| 55 { | |
| 56 unitElement = unit.element; | |
| 57 unitLibraryElement = unitElement.library; | |
| 58 } | |
| 59 | |
| 60 DartType get coreTypeBool => _getCoreType("bool"); | |
| 49 | 61 |
| 50 List<Fix> compute() { | 62 List<Fix> compute() { |
| 51 utils = new CorrectionUtils(unit); | 63 utils = new CorrectionUtils(unit); |
| 52 errorOffset = error.offset; | 64 errorOffset = error.offset; |
| 53 errorLength = error.length; | 65 errorLength = error.length; |
| 54 errorEnd = errorOffset + errorLength; | 66 errorEnd = errorOffset + errorLength; |
| 55 node = new NodeLocator.con1(errorOffset).searchWithin(unit); | 67 node = new NodeLocator.con1(errorOffset).searchWithin(unit); |
| 56 coveredNode = new NodeLocator.con2( | 68 coveredNode = new NodeLocator.con2( |
| 57 errorOffset, | 69 errorOffset, |
| 58 errorOffset + errorLength).searchWithin(unit); | 70 errorOffset + errorLength).searchWithin(unit); |
| 59 // analyze ErrorCode | 71 // analyze ErrorCode |
| 60 ErrorCode errorCode = error.errorCode; | 72 ErrorCode errorCode = error.errorCode; |
| 61 if (errorCode == StaticWarningCode.UNDEFINED_CLASS_BOOLEAN) { | 73 if (errorCode == StaticWarningCode.UNDEFINED_CLASS_BOOLEAN) { |
| 62 _addFix_boolInsteadOfBoolean(); | 74 _addFix_boolInsteadOfBoolean(); |
| 63 } | 75 } |
| 64 if (errorCode == | 76 if (errorCode == |
| 65 CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE) { | 77 CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE) { |
| 66 _addFix_replaceWithConstInstanceCreation(); | 78 _addFix_replaceWithConstInstanceCreation(); |
| 67 } | 79 } |
| 68 if (errorCode == | 80 if (errorCode == |
| 69 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT) { | 81 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT) { |
| 70 _addFix_createConstructorSuperExplicit(); | 82 _addFix_createConstructorSuperExplicit(); |
| 71 } | 83 } |
| 72 // if (identical( | 84 if (errorCode == |
| 73 // errorCode, | 85 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT) { |
| 74 // CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT)) { | 86 _addFix_createConstructorSuperImplicit(); |
| 75 // _addFix_createConstructorSuperImplicit(); | 87 } |
| 76 // } | |
| 77 if (errorCode == | 88 if (errorCode == |
| 78 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT) { | 89 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT) { |
| 79 _addFix_createConstructorSuperExplicit(); | 90 _addFix_createConstructorSuperExplicit(); |
| 80 } | 91 } |
| 81 // if (identical(errorCode, CompileTimeErrorCode.URI_DOES_NOT_EXIST)) { | 92 // if (identical(errorCode, CompileTimeErrorCode.URI_DOES_NOT_EXIST)) { |
| 82 // _addFix_createPart(); | 93 // _addFix_createPart(); |
| 83 // _addFix_addPackageDependency(); | 94 // _addFix_addPackageDependency(); |
| 84 // } | 95 // } |
| 85 if (errorCode == HintCode.DIVISION_OPTIMIZATION) { | 96 if (errorCode == HintCode.DIVISION_OPTIMIZATION) { |
| 86 _addFix_useEffectiveIntegerDivision(); | 97 _addFix_useEffectiveIntegerDivision(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 132 List<ExecutableElement> missingOverrides = | 143 List<ExecutableElement> missingOverrides = |
| 133 property as List<ExecutableElement>; | 144 property as List<ExecutableElement>; |
| 134 _addFix_createMissingOverrides(missingOverrides); | 145 _addFix_createMissingOverrides(missingOverrides); |
| 135 _addFix_createNoSuchMethod(); | 146 _addFix_createNoSuchMethod(); |
| 136 } | 147 } |
| 137 if (errorCode == StaticWarningCode.UNDEFINED_CLASS) { | 148 if (errorCode == StaticWarningCode.UNDEFINED_CLASS) { |
| 138 _addFix_importLibrary_withType(); | 149 _addFix_importLibrary_withType(); |
| 139 _addFix_createClass(); | 150 _addFix_createClass(); |
| 140 _addFix_undefinedClass_useSimilar(); | 151 _addFix_undefinedClass_useSimilar(); |
| 141 } | 152 } |
| 142 // if (identical(errorCode, StaticWarningCode.UNDEFINED_IDENTIFIER)) { | 153 if (errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER) { |
| 143 // _addFix_createFunction_forFunctionType(); | 154 _addFix_createFunction_forFunctionType(); |
| 144 // _addFix_importLibrary_withType(); | 155 _addFix_importLibrary_withType(); |
| 145 // _addFix_importLibrary_withTopLevelVariable(); | 156 _addFix_importLibrary_withTopLevelVariable(); |
| 146 // } | 157 } |
| 147 if (errorCode == StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER) { | 158 if (errorCode == StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER) { |
| 148 _addFix_useStaticAccess_method(); | 159 _addFix_useStaticAccess_method(); |
| 149 _addFix_useStaticAccess_property(); | 160 _addFix_useStaticAccess_property(); |
| 150 } | 161 } |
| 151 if (errorCode == StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) { | 162 if (errorCode == StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) { |
| 152 _addFix_removeParentheses_inGetterInvocation(); | 163 _addFix_removeParentheses_inGetterInvocation(); |
| 153 } | 164 } |
| 154 // if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) { | 165 // if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) { |
| 155 // _addFix_importLibrary_withFunction(); | 166 // _addFix_importLibrary_withFunction(); |
| 156 // _addFix_undefinedFunction_useSimilar(); | 167 // _addFix_undefinedFunction_useSimilar(); |
| 157 // _addFix_undefinedFunction_create(); | 168 // _addFix_undefinedFunction_create(); |
| 158 // } | 169 // } |
| 159 // if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_GETTER)) { | 170 if (errorCode == StaticTypeWarningCode.UNDEFINED_GETTER) { |
| 160 // _addFix_createFunction_forFunctionType(); | 171 _addFix_createFunction_forFunctionType(); |
| 161 // } | 172 } |
| 162 // if (identical(errorCode, HintCode.UNDEFINED_METHOD) || | 173 if (errorCode == HintCode.UNDEFINED_METHOD || |
| 163 // identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { | 174 errorCode == StaticTypeWarningCode.UNDEFINED_METHOD) { |
| 164 // _addFix_undefinedMethod_useSimilar(); | 175 _addFix_undefinedMethod_useSimilar(); |
| 165 // _addFix_undefinedMethod_create(); | 176 _addFix_undefinedMethod_create(); |
| 166 // _addFix_undefinedFunction_create(); | 177 _addFix_undefinedFunction_create(); |
| 167 // } | 178 } |
| 168 // done | 179 // done |
| 169 return fixes; | 180 return fixes; |
| 170 } | 181 } |
| 171 | 182 |
| 172 void _addFix(FixKind kind, List args, {String fixFile}) { | 183 void _addFix(FixKind kind, List args, {String fixFile}) { |
| 173 if (fixFile == null) { | 184 if (fixFile == null) { |
| 174 fixFile = file; | 185 fixFile = file; |
| 175 } | 186 } |
| 176 FileEdit fileEdit = new FileEdit(file); | 187 FileEdit fileEdit = new FileEdit(file); |
| 177 edits.forEach((edit) => fileEdit.add(edit)); | 188 edits.forEach((edit) => fileEdit.add(edit)); |
| 178 // prepare Change | 189 // prepare Change |
| 179 String message = JavaString.format(kind.message, args); | 190 String message = JavaString.format(kind.message, args); |
| 180 Change change = new Change(message); | 191 Change change = new Change(message); |
| 181 change.add(fileEdit); | 192 change.add(fileEdit); |
| 182 linkedPositionGroups.values.forEach( | 193 linkedPositionGroups.values.forEach( |
| 183 (group) => change.addLinkedPositionGroup(group)); | 194 (group) => change.addLinkedPositionGroup(group)); |
| 195 change.endPosition = endPosition; | |
| 184 // add Fix | 196 // add Fix |
| 185 Fix fix = new Fix(kind, change); | 197 Fix fix = new Fix(kind, change); |
| 186 fixes.add(fix); | 198 fixes.add(fix); |
| 199 // clear | |
| 200 edits.clear(); | |
| 201 linkedPositionGroups.clear(); | |
| 202 endPosition = null; | |
| 187 } | 203 } |
| 188 | 204 |
| 189 void _addFix_addPackageDependency() { | 205 void _addFix_addPackageDependency() { |
| 190 // TODO(scheglov) implement | 206 // TODO(scheglov) implement |
| 191 // if (node is SimpleStringLiteral && node.parent is NamespaceDirective) { | 207 // if (node is SimpleStringLiteral && node.parent is NamespaceDirective) { |
| 192 // SimpleStringLiteral uriLiteral = node as SimpleStringLiteral; | 208 // SimpleStringLiteral uriLiteral = node as SimpleStringLiteral; |
| 193 // String uriString = uriLiteral.value; | 209 // String uriString = uriLiteral.value; |
| 194 // // we need package: import | 210 // // we need package: import |
| 195 // if (!uriString.startsWith("package:")) { | 211 // if (!uriString.startsWith("package:")) { |
| 196 // return; | 212 // return; |
| 197 // } | 213 // } |
| 198 // // prepare package name | 214 // // prepare package name |
| 199 // String packageName = StringUtils.removeStart(uriString, "package:"); | 215 // String packageName = StringUtils.removeStart(uriString, "package:"); |
| 200 // packageName = StringUtils.substringBefore(packageName, "/"); | 216 // packageName = StringUtils.substringBefore(packageName, "/"); |
| 201 // // add proposal | 217 // // add proposal |
| 202 // _proposals.add( | 218 // _proposals.add( |
| 203 // new AddDependencyCorrectionProposal( | 219 // new AddDependencyCorrectionProposal( |
| 204 // _unitFile, | 220 // _unitFile, |
| 205 // packageName, | 221 // packageName, |
| 206 // FixKind.ADD_PACKAGE_DEPENDENCY, | 222 // FixKind.ADD_PACKAGE_DEPENDENCY, |
| 207 // [packageName])); | 223 // [packageName])); |
| 208 // } | 224 // } |
| 209 } | 225 } |
| 210 | 226 |
| 227 | |
| 211 void _addFix_boolInsteadOfBoolean() { | 228 void _addFix_boolInsteadOfBoolean() { |
| 212 SourceRange range = rf.rangeError(error); | 229 SourceRange range = rf.rangeError(error); |
| 213 _addReplaceEdit(range, "bool"); | 230 _addReplaceEdit(range, "bool"); |
| 214 _addFix(FixKind.REPLACE_BOOLEAN_WITH_BOOL, []); | 231 _addFix(FixKind.REPLACE_BOOLEAN_WITH_BOOL, []); |
| 215 } | 232 } |
| 216 | 233 |
| 217 | 234 |
| 218 void _addFix_createClass() { | 235 void _addFix_createClass() { |
| 219 if (_mayBeTypeIdentifier(node)) { | 236 if (_mayBeTypeIdentifier(node)) { |
| 220 String name = (node as SimpleIdentifier).name; | 237 String name = (node as SimpleIdentifier).name; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 243 sb.append("}"); | 260 sb.append("}"); |
| 244 } | 261 } |
| 245 // insert source | 262 // insert source |
| 246 _insertBuilder(sb); | 263 _insertBuilder(sb); |
| 247 _addLinkedPosition("NAME", rf.rangeNode(node)); | 264 _addLinkedPosition("NAME", rf.rangeNode(node)); |
| 248 // add proposal | 265 // add proposal |
| 249 _addFix(FixKind.CREATE_CLASS, [name]); | 266 _addFix(FixKind.CREATE_CLASS, [name]); |
| 250 } | 267 } |
| 251 } | 268 } |
| 252 | 269 |
| 253 | |
| 254 void _addFix_createConstructorSuperExplicit() { | 270 void _addFix_createConstructorSuperExplicit() { |
| 255 ConstructorDeclaration targetConstructor = | 271 ConstructorDeclaration targetConstructor = |
| 256 node.parent as ConstructorDeclaration; | 272 node.parent as ConstructorDeclaration; |
| 257 ClassDeclaration targetClassNode = | 273 ClassDeclaration targetClassNode = |
| 258 targetConstructor.parent as ClassDeclaration; | 274 targetConstructor.parent as ClassDeclaration; |
| 259 ClassElement targetClassElement = targetClassNode.element; | 275 ClassElement targetClassElement = targetClassNode.element; |
| 260 ClassElement superClassElement = targetClassElement.supertype.element; | 276 ClassElement superClassElement = targetClassElement.supertype.element; |
| 261 // add proposals for all super constructors | 277 // add proposals for all super constructors |
| 262 List<ConstructorElement> superConstructors = superClassElement.constructors; | 278 List<ConstructorElement> superConstructors = superClassElement.constructors; |
| 263 for (ConstructorElement superConstructor in superConstructors) { | 279 for (ConstructorElement superConstructor in superConstructors) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 312 sb.append(")"); | 328 sb.append(")"); |
| 313 // insert proposal | 329 // insert proposal |
| 314 _insertBuilder(sb); | 330 _insertBuilder(sb); |
| 315 // add proposal | 331 // add proposal |
| 316 String proposalName = _getConstructorProposalName(superConstructor); | 332 String proposalName = _getConstructorProposalName(superConstructor); |
| 317 _addFix(FixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, [proposalName]); | 333 _addFix(FixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, [proposalName]); |
| 318 } | 334 } |
| 319 } | 335 } |
| 320 | 336 |
| 321 void _addFix_createConstructorSuperImplicit() { | 337 void _addFix_createConstructorSuperImplicit() { |
| 322 // TODO(scheglov) implement | 338 ClassDeclaration targetClassNode = node.parent as ClassDeclaration; |
| 323 // ClassDeclaration targetClassNode = node.parent as ClassDeclaration; | 339 ClassElement targetClassElement = targetClassNode.element; |
| 324 // ClassElement targetClassElement = targetClassNode.element; | 340 ClassElement superClassElement = targetClassElement.supertype.element; |
| 325 // ClassElement superClassElement = targetClassElement.supertype.element; | 341 String targetClassName = targetClassElement.name; |
| 326 // String targetClassName = targetClassElement.name; | 342 // add proposals for all super constructors |
| 327 // // add proposals for all super constructors | 343 List<ConstructorElement> superConstructors = superClassElement.constructors; |
| 328 // List<ConstructorElement> superConstructors = superClassElement.constructor s; | 344 for (ConstructorElement superConstructor in superConstructors) { |
| 329 // for (ConstructorElement superConstructor in superConstructors) { | 345 String constructorName = superConstructor.name; |
| 330 // String constructorName = superConstructor.name; | 346 // skip private |
| 331 // // skip private | 347 if (Identifier.isPrivateName(constructorName)) { |
| 332 // if (Identifier.isPrivateName(constructorName)) { | 348 continue; |
| 333 // continue; | 349 } |
| 334 // } | 350 // prepare parameters and arguments |
| 335 // // prepare parameters and arguments | 351 StringBuffer parametersBuffer = new StringBuffer(); |
| 336 // JavaStringBuilder parametersBuffer = new JavaStringBuilder(); | 352 StringBuffer argumentsBuffer = new StringBuffer(); |
| 337 // JavaStringBuilder argumentsBuffer = new JavaStringBuilder(); | 353 bool firstParameter = true; |
| 338 // bool firstParameter = true; | 354 for (ParameterElement parameter in superConstructor.parameters) { |
| 339 // for (ParameterElement parameter in superConstructor.parameters) { | 355 // skip non-required parameters |
| 340 // // skip non-required parameters | 356 if (parameter.parameterKind != ParameterKind.REQUIRED) { |
| 341 // if (parameter.parameterKind != ParameterKind.REQUIRED) { | 357 break; |
| 342 // break; | 358 } |
| 343 // } | 359 // comma |
| 344 // // comma | 360 if (firstParameter) { |
| 345 // if (firstParameter) { | 361 firstParameter = false; |
| 346 // firstParameter = false; | 362 } else { |
| 347 // } else { | 363 parametersBuffer.write(', '); |
| 348 // parametersBuffer.append(", "); | 364 argumentsBuffer.write(', '); |
| 349 // argumentsBuffer.append(", "); | 365 } |
| 350 // } | 366 // name |
| 351 // // name | 367 String parameterName = parameter.displayName; |
| 352 // String parameterName = parameter.displayName; | 368 if (parameterName.length > 1 && parameterName.startsWith('_')) { |
| 353 // if (parameterName.length > 1 && parameterName.startsWith("_")) { | 369 parameterName = parameterName.substring(1); |
| 354 // parameterName = parameterName.substring(1); | 370 } |
| 355 // } | 371 // parameter & argument |
| 356 // // parameter & argument | 372 _appendParameterSource(parametersBuffer, parameter.type, parameterName); |
| 357 // _appendParameterSource(parametersBuffer, parameter.type, parameterName ); | 373 argumentsBuffer.write(parameterName); |
| 358 // argumentsBuffer.append(parameterName); | 374 } |
| 359 // } | 375 // add proposal |
| 360 // // add proposal | 376 String eol = utils.endOfLine; |
|
Paul Berry
2014/07/25 00:28:46
With my suggestion about eol below, this line coul
scheglov
2014/07/25 03:20:50
Done.
| |
| 361 // String eol = utils.endOfLine; | 377 QuickFixProcessorImpl_NewConstructorLocation targetLocation = |
| 362 // QuickFixProcessorImpl_NewConstructorLocation targetLocation = | 378 _prepareNewConstructorLocation(targetClassNode, eol); |
| 363 // _prepareNewConstructorLocation(targetClassNode, eol); | 379 SourceBuilder sb = new SourceBuilder(file, targetLocation._offset); |
| 364 // SourceBuilder sb = new SourceBuilder.con1(targetLocation._offset); | 380 { |
| 365 // { | 381 String indent = utils.getIndent(1); |
| 366 // String indent = utils.getIndent(1); | 382 sb.append(targetLocation._prefix); |
| 367 // sb.append(targetLocation._prefix); | 383 sb.append(indent); |
| 368 // sb.append(indent); | 384 sb.append(targetClassName); |
| 369 // sb.append(targetClassName); | 385 if (!constructorName.isEmpty) { |
| 370 // if (!constructorName.isEmpty) { | 386 sb.startPosition('NAME'); |
|
Paul Berry
2014/07/25 00:28:45
Are the strings passed to startPosition things tha
scheglov
2014/07/25 03:20:51
These strings are IDs of linked position groups.
T
| |
| 371 // sb.startPosition("NAME"); | 387 sb.append('.'); |
| 372 // sb.append("."); | 388 sb.append(constructorName); |
| 373 // sb.append(constructorName); | 389 sb.endPosition(); |
| 374 // sb.endPosition(); | 390 } |
| 375 // } | 391 sb.append("("); |
| 376 // sb.append("("); | 392 sb.append(parametersBuffer.toString()); |
| 377 // sb.append(parametersBuffer.toString()); | 393 sb.append(') : super'); |
| 378 // sb.append(") : super"); | 394 if (!constructorName.isEmpty) { |
| 379 // if (!constructorName.isEmpty) { | 395 sb.append('.'); |
| 380 // sb.append("."); | 396 sb.append(constructorName); |
| 381 // sb.append(constructorName); | 397 } |
| 382 // } | 398 sb.append('('); |
| 383 // sb.append("("); | 399 sb.append(argumentsBuffer.toString()); |
| 384 // sb.append(argumentsBuffer.toString()); | 400 sb.append(');'); |
| 385 // sb.append(");"); | 401 sb.append(targetLocation._suffix); |
| 386 // sb.append(targetLocation._suffix); | 402 } |
| 387 // } | 403 _insertBuilder(sb); |
| 388 // _addInsertEdit3(sb); | 404 // add proposal |
| 389 // // add proposal | 405 String proposalName = _getConstructorProposalName(superConstructor); |
| 390 // String proposalName = _getConstructorProposalName(superConstructor); | 406 _addFix(FixKind.CREATE_CONSTRUCTOR_SUPER, [proposalName]); |
| 391 // _addFix( | 407 } |
| 392 // FixKind.CREATE_CONSTRUCTOR_SUPER, | |
| 393 // [proposalName]); | |
| 394 // } | |
| 395 } | 408 } |
| 396 | 409 |
| 397 void _addFix_createConstructor_insteadOfSyntheticDefault() { | 410 void _addFix_createConstructor_insteadOfSyntheticDefault() { |
| 398 TypeName typeName = null; | 411 TypeName typeName = null; |
| 399 ConstructorName constructorName = null; | 412 ConstructorName constructorName = null; |
| 400 InstanceCreationExpression instanceCreation = null; | 413 InstanceCreationExpression instanceCreation = null; |
| 401 if (node is SimpleIdentifier) { | 414 if (node is SimpleIdentifier) { |
| 402 if (node.parent is TypeName) { | 415 if (node.parent is TypeName) { |
| 403 typeName = node.parent as TypeName; | 416 typeName = node.parent as TypeName; |
| 404 if (typeName.name == node && typeName.parent is ConstructorName) { | 417 if (typeName.name == node && typeName.parent is ConstructorName) { |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 520 // insert source | 533 // insert source |
| 521 _insertBuilder(sb); | 534 _insertBuilder(sb); |
| 522 if (targetFile == file) { | 535 if (targetFile == file) { |
| 523 _addLinkedPosition("NAME", rf.rangeNode(name)); | 536 _addLinkedPosition("NAME", rf.rangeNode(name)); |
| 524 } | 537 } |
| 525 // add proposal | 538 // add proposal |
| 526 _addFix(FixKind.CREATE_CONSTRUCTOR, [constructorName], fixFile: targetFile); | 539 _addFix(FixKind.CREATE_CONSTRUCTOR, [constructorName], fixFile: targetFile); |
| 527 } | 540 } |
| 528 | 541 |
| 529 void _addFix_createFunction_forFunctionType() { | 542 void _addFix_createFunction_forFunctionType() { |
| 530 // TODO(scheglov) implement | 543 if (node is SimpleIdentifier) { |
| 531 // if (node is SimpleIdentifier) { | 544 SimpleIdentifier nameNode = node as SimpleIdentifier; |
| 532 // SimpleIdentifier nameNode = node as SimpleIdentifier; | 545 // prepare argument expression (to get parameter) |
| 533 // // prepare argument expression (to get parameter) | 546 ClassElement targetElement; |
| 534 // ClassElement targetElement; | 547 Expression argument; |
| 535 // Expression argument; | 548 { |
| 536 // { | 549 Expression target = getQualifiedPropertyTarget(node); |
| 537 // Expression target = CorrectionUtils.getQualifiedPropertyTarget(node); | 550 if (target != null) { |
| 538 // if (target != null) { | 551 DartType targetType = target.bestType; |
| 539 // DartType targetType = target.bestType; | 552 if (targetType != null && targetType.element is ClassElement) { |
| 540 // if (targetType != null && targetType.element is ClassElement) { | 553 targetElement = targetType.element as ClassElement; |
| 541 // targetElement = targetType.element as ClassElement; | 554 argument = target.parent as Expression; |
| 542 // argument = target.parent as Expression; | 555 } else { |
| 543 // } else { | 556 return; |
| 544 // return; | 557 } |
| 545 // } | 558 } else { |
| 546 // } else { | 559 ClassDeclaration enclosingClass = |
| 547 // ClassDeclaration enclosingClass = | 560 node.getAncestor((node) => node is ClassDeclaration); |
| 548 // node.getAncestor((node) => node is ClassDeclaration); | 561 targetElement = enclosingClass != null ? |
| 549 // targetElement = enclosingClass != null ? | 562 enclosingClass.element : |
| 550 // enclosingClass.element : | 563 null; |
| 551 // null; | 564 argument = nameNode; |
| 552 // argument = nameNode; | 565 } |
| 553 // } | 566 } |
| 554 // } | 567 // should be argument of some invocation |
| 555 // // should be argument of some invocation | 568 ParameterElement parameterElement = argument.bestParameterElement; |
| 556 // ParameterElement parameterElement = argument.bestParameterElement; | 569 if (parameterElement == null) { |
| 557 // if (parameterElement == null) { | 570 return; |
| 558 // return; | 571 } |
| 559 // } | 572 // should be parameter of function type |
| 560 // // should be parameter of function type | 573 DartType parameterType = parameterElement.type; |
| 561 // DartType parameterType = parameterElement.type; | 574 if (parameterType is! FunctionType) { |
| 562 // if (parameterType is! FunctionType) { | 575 return; |
| 563 // return; | 576 } |
| 564 // } | 577 FunctionType functionType = parameterType as FunctionType; |
| 565 // FunctionType functionType = parameterType as FunctionType; | 578 // add proposal |
| 566 // // add proposal | 579 if (targetElement != null) { |
| 567 // if (targetElement != null) { | 580 _addProposal_createFunction_method(targetElement, functionType); |
| 568 // _addProposal_createFunction_method(targetElement, functionType); | 581 } else { |
| 569 // } else { | 582 _addProposal_createFunction_function(functionType); |
| 570 // _addProposal_createFunction_function(functionType); | 583 } |
| 571 // } | 584 } |
| 572 // } | |
| 573 } | 585 } |
| 574 | 586 |
| 575 void | 587 void |
| 576 _addFix_createMissingOverrides(List<ExecutableElement> missingOverrides) { | 588 _addFix_createMissingOverrides(List<ExecutableElement> missingOverrides) { |
| 577 // TODO(scheglov) implement | 589 // sort by name |
| 578 // // sort by name | 590 missingOverrides.sort((Element firstElement, Element secondElement) { |
| 579 // missingOverrides.sort( | 591 return compareStrings( |
| 580 // (Element firstElement, Element secondElement) => | 592 firstElement.displayName, |
| 581 // ObjectUtils.compare(firstElement.displayName, secondElement.displa yName)); | 593 secondElement.displayName); |
| 582 // // add elements | 594 }); |
| 583 // ClassDeclaration targetClass = node.parent as ClassDeclaration; | 595 // add elements |
| 584 // bool isFirst = true; | 596 ClassDeclaration targetClass = node.parent as ClassDeclaration; |
| 585 // for (ExecutableElement missingOverride in missingOverrides) { | 597 bool isFirst = true; |
| 586 // _addFix_createMissingOverrides_single( | 598 for (ExecutableElement missingOverride in missingOverrides) { |
| 587 // targetClass, | 599 _addFix_createMissingOverrides_single( |
| 588 // missingOverride, | 600 targetClass, |
| 589 // isFirst); | 601 missingOverride, |
| 590 // isFirst = false; | 602 isFirst); |
| 591 // } | 603 isFirst = false; |
| 592 // // add proposal | 604 } |
| 593 // _addFix( | 605 // add proposal |
| 594 // FixKind.CREATE_MISSING_OVERRIDES, | 606 _addFix(FixKind.CREATE_MISSING_OVERRIDES, [missingOverrides.length]); |
| 595 // [missingOverrides.length]); | |
| 596 } | 607 } |
| 597 | 608 |
| 598 void _addFix_createMissingOverrides_single(ClassDeclaration targetClass, | 609 void _addFix_createMissingOverrides_single(ClassDeclaration targetClass, |
| 599 ExecutableElement missingOverride, bool isFirst) { | 610 ExecutableElement missingOverride, bool isFirst) { |
| 600 // TODO(scheglov) implement | 611 // prepare environment |
| 601 // // prepare environment | 612 String eol = utils.endOfLine; |
| 602 // String eol = utils.endOfLine; | 613 String prefix = utils.getIndent(1); |
| 603 // String prefix = utils.getIndent(1); | 614 String prefix2 = utils.getIndent(2); |
| 604 // String prefix2 = utils.getIndent(2); | 615 int insertOffset = targetClass.end - 1; |
| 605 // int insertOffset = targetClass.end - 1; | 616 // prepare source |
| 606 // // prepare source | 617 StringBuffer sb = new StringBuffer(); |
| 607 // JavaStringBuilder sb = new JavaStringBuilder(); | 618 // may be empty line |
| 608 // // may be empty line | 619 if (!isFirst || !targetClass.members.isEmpty) { |
| 609 // if (!isFirst || !targetClass.members.isEmpty) { | 620 sb.write(eol); |
| 610 // sb.append(eol); | 621 } |
| 611 // } | 622 // may be property |
| 612 // // may be property | 623 ElementKind elementKind = missingOverride.kind; |
| 613 // ElementKind elementKind = missingOverride.kind; | 624 bool isGetter = elementKind == ElementKind.GETTER; |
| 614 // bool isGetter = elementKind == ElementKind.GETTER; | 625 bool isSetter = elementKind == ElementKind.SETTER; |
| 615 // bool isSetter = elementKind == ElementKind.SETTER; | 626 bool isMethod = elementKind == ElementKind.METHOD; |
| 616 // bool isMethod = elementKind == ElementKind.METHOD; | 627 bool isOperator = isMethod && (missingOverride as MethodElement).isOperator; |
| 617 // bool isOperator = isMethod && (missingOverride as MethodElement).isOperato r; | 628 sb.write(prefix); |
| 618 // sb.append(prefix); | 629 if (isGetter) { |
| 619 // if (isGetter) { | 630 sb.write('// TODO: implement ${missingOverride.displayName}'); |
| 620 // sb.append("// TODO: implement ${missingOverride.displayName}"); | 631 sb.write(eol); |
| 621 // sb.append(eol); | 632 sb.write(prefix); |
| 622 // sb.append(prefix); | 633 } |
| 623 // } | 634 // @override |
| 624 // // @override | 635 { |
| 625 // { | 636 sb.write('@override'); |
| 626 // sb.append("@override"); | 637 sb.write(eol); |
| 627 // sb.append(eol); | 638 sb.write(prefix); |
| 628 // sb.append(prefix); | 639 } |
| 629 // } | 640 // return type |
| 630 // // return type | 641 _appendType(sb, missingOverride.type.returnType); |
| 631 // _appendType(sb, missingOverride.type.returnType); | 642 if (isGetter) { |
| 632 // if (isGetter) { | 643 sb.write('get '); |
| 633 // sb.append("get "); | 644 } else if (isSetter) { |
| 634 // } else if (isSetter) { | 645 sb.write('set '); |
| 635 // sb.append("set "); | 646 } else if (isOperator) { |
| 636 // } else if (isOperator) { | 647 sb.write('operator '); |
| 637 // sb.append("operator "); | 648 } |
| 638 // } | 649 // name |
| 639 // // name | 650 sb.write(missingOverride.displayName); |
| 640 // sb.append(missingOverride.displayName); | 651 // parameters + body |
| 641 // // parameters + body | 652 if (isGetter) { |
| 642 // if (isGetter) { | 653 sb.write(' => null;'); |
| 643 // sb.append(" => null;"); | 654 } else if (isMethod || isSetter) { |
|
Paul Berry
2014/07/25 00:28:45
Any reason this couldn't just be "} else {"?
scheglov
2014/07/25 03:20:51
Done.
| |
| 644 // } else if (isMethod || isSetter) { | 655 List<ParameterElement> parameters = missingOverride.parameters; |
| 645 // List<ParameterElement> parameters = missingOverride.parameters; | 656 _appendParameters(sb, parameters, _getDefaultValueMap(parameters)); |
| 646 // _appendParameters(sb, parameters); | 657 sb.write(' {'); |
| 647 // sb.append(" {"); | 658 // TO-DO |
| 648 // // TO-DO | 659 sb.write(eol); |
| 649 // sb.append(eol); | 660 sb.write(prefix2); |
| 650 // sb.append(prefix2); | 661 if (isMethod) { |
|
Paul Berry
2014/07/25 00:28:45
This if test is unnecessary, since we do the same
scheglov
2014/07/25 03:20:51
Done.
| |
| 651 // if (isMethod) { | 662 sb.write('// TODO: implement ${missingOverride.displayName}'); |
| 652 // sb.append("// TODO: implement ${missingOverride.displayName}"); | 663 } else { |
| 653 // } else { | 664 sb.write('// TODO: implement ${missingOverride.displayName}'); |
| 654 // sb.append("// TODO: implement ${missingOverride.displayName}"); | 665 } |
| 655 // } | 666 sb.write(eol); |
| 656 // sb.append(eol); | 667 // close method |
| 657 // // close method | 668 sb.write(prefix); |
| 658 // sb.append(prefix); | 669 sb.write('}'); |
| 659 // sb.append("}"); | 670 } |
| 660 // } | 671 sb.write(eol); |
| 661 // sb.append(eol); | 672 // done |
| 662 // // done | 673 _addInsertEdit(insertOffset, sb.toString()); |
| 663 // _addInsertEdit(insertOffset, sb.toString()); | 674 // maybe set end range |
| 664 // // maybe set end range | 675 if (endPosition == null) { |
| 665 // if (_endRange == null) { | 676 endPosition = new Position(file, insertOffset, 0); |
| 666 // _endRange = SourceRangeFactory.rangeStartLength(insertOffset, 0); | 677 } |
| 667 // } | |
| 668 } | 678 } |
| 669 | 679 |
| 670 void _addFix_createNoSuchMethod() { | 680 void _addFix_createNoSuchMethod() { |
| 671 // TODO(scheglov) implement | 681 ClassDeclaration targetClass = node.parent as ClassDeclaration; |
| 672 // ClassDeclaration targetClass = node.parent as ClassDeclaration; | 682 // prepare environment |
| 673 // // prepare environment | 683 String eol = utils.endOfLine; |
| 674 // String eol = utils.endOfLine; | 684 String prefix = utils.getIndent(1); |
| 675 // String prefix = utils.getIndent(1); | 685 int insertOffset = targetClass.end - 1; |
| 676 // int insertOffset = targetClass.end - 1; | 686 // prepare source |
| 677 // // prepare source | 687 SourceBuilder sb = new SourceBuilder(file, insertOffset); |
| 678 // SourceBuilder sb = new SourceBuilder.con1(insertOffset); | 688 { |
| 679 // { | 689 // insert empty line before existing member |
| 680 // // insert empty line before existing member | 690 if (!targetClass.members.isEmpty) { |
| 681 // if (!targetClass.members.isEmpty) { | 691 sb.append(eol); |
| 682 // sb.append(eol); | 692 } |
| 683 // } | 693 // append method |
| 684 // // append method | 694 sb.append(prefix); |
| 685 // sb.append(prefix); | 695 sb.append( |
| 686 // sb.append( | 696 "noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation) ;"); |
| 687 // "noSuchMethod(Invocation invocation) => super.noSuchMethod(invocatio n);"); | 697 sb.append(eol); |
| 688 // sb.append(eol); | 698 } |
| 689 // } | 699 // done |
| 690 // // done | 700 _insertBuilder(sb); |
| 691 // _addInsertEdit3(sb); | 701 endPosition = new Position(file, insertOffset, 0); |
| 692 // _endRange = SourceRangeFactory.rangeStartLength(insertOffset, 0); | 702 // add proposal |
| 693 // // add proposal | 703 _addFix(FixKind.CREATE_NO_SUCH_METHOD, []); |
| 694 // _addFix(FixKind.CREATE_NO_SUCH_METHOD, []); | |
| 695 } | 704 } |
| 696 | 705 |
| 697 void _addFix_createPart() { | 706 void _addFix_createPart() { |
| 698 // TODO(scheglov) implement | 707 // TODO(scheglov) implement |
| 699 // if (node is SimpleStringLiteral && node.parent is PartDirective) { | 708 // if (node is SimpleStringLiteral && node.parent is PartDirective) { |
| 700 // SimpleStringLiteral uriLiteral = node as SimpleStringLiteral; | 709 // SimpleStringLiteral uriLiteral = node as SimpleStringLiteral; |
| 701 // String uriString = uriLiteral.value; | 710 // String uriString = uriLiteral.value; |
| 702 // // prepare referenced File | 711 // // prepare referenced File |
| 703 // JavaFile newFile; | 712 // JavaFile newFile; |
| 704 // { | 713 // { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 720 // _proposals.add( | 729 // _proposals.add( |
| 721 // new CreateFileCorrectionProposal( | 730 // new CreateFileCorrectionProposal( |
| 722 // newFile, | 731 // newFile, |
| 723 // source, | 732 // source, |
| 724 // FixKind.CREATE_PART, | 733 // FixKind.CREATE_PART, |
| 725 // [uriString])); | 734 // [uriString])); |
| 726 // } | 735 // } |
| 727 // } | 736 // } |
| 728 } | 737 } |
| 729 | 738 |
| 739 | |
| 730 void _addFix_importLibrary(FixKind kind, String importPath) { | 740 void _addFix_importLibrary(FixKind kind, String importPath) { |
| 731 // TODO(scheglov) implement | 741 // TODO(scheglov) implement |
| 732 // CompilationUnitElement libraryUnitElement = | 742 // CompilationUnitElement libraryUnitElement = |
| 733 // _unitLibraryElement.definingCompilationUnit; | 743 // _unitLibraryElement.definingCompilationUnit; |
| 734 // CompilationUnit libraryUnit = libraryUnitElement.node; | 744 // CompilationUnit libraryUnit = libraryUnitElement.node; |
| 735 // // prepare new import location | 745 // // prepare new import location |
| 736 // int offset = 0; | 746 // int offset = 0; |
| 737 // String prefix; | 747 // String prefix; |
| 738 // String suffix; | 748 // String suffix; |
| 739 // { | 749 // { |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1144 // String closestName = null; | 1154 // String closestName = null; |
| 1145 // if (finder != null && finder._distance < 5) { | 1155 // if (finder != null && finder._distance < 5) { |
| 1146 // closestName = finder._element.name; | 1156 // closestName = finder._element.name; |
| 1147 // _addReplaceEdit(SourceRangeFactory.rangeNode(node), closestName); | 1157 // _addReplaceEdit(SourceRangeFactory.rangeNode(node), closestName); |
| 1148 // _addFix(FixKind.CHANGE_TO, [closestName]); | 1158 // _addFix(FixKind.CHANGE_TO, [closestName]); |
| 1149 // } | 1159 // } |
| 1150 // } | 1160 // } |
| 1151 } | 1161 } |
| 1152 | 1162 |
| 1153 void _addFix_undefinedMethod_create() { | 1163 void _addFix_undefinedMethod_create() { |
| 1154 // TODO(scheglov) implement | 1164 if (node is SimpleIdentifier && node.parent is MethodInvocation) { |
| 1155 // if (node is SimpleIdentifier && node.parent is MethodInvocation) { | 1165 String name = (node as SimpleIdentifier).name; |
| 1156 // String name = (node as SimpleIdentifier).name; | 1166 MethodInvocation invocation = node.parent as MethodInvocation; |
| 1157 // MethodInvocation invocation = node.parent as MethodInvocation; | 1167 // prepare environment |
| 1158 // // prepare environment | 1168 String eol = utils.endOfLine; |
| 1159 // String eol = utils.endOfLine; | 1169 Source targetSource; |
| 1160 // Source targetSource; | 1170 String prefix; |
| 1161 // String prefix; | 1171 int insertOffset; |
| 1162 // int insertOffset; | 1172 String sourcePrefix; |
| 1163 // String sourcePrefix; | 1173 String sourceSuffix; |
| 1164 // String sourceSuffix; | 1174 bool staticModifier = false; |
| 1165 // bool staticModifier = false; | 1175 Expression target = invocation.realTarget; |
| 1166 // Expression target = invocation.realTarget; | 1176 if (target == null) { |
| 1167 // if (target == null) { | 1177 targetSource = source; |
| 1168 // targetSource = _source; | 1178 ClassMember enclosingMember = |
| 1169 // ClassMember enclosingMember = | 1179 node.getAncestor((node) => node is ClassMember); |
| 1170 // node.getAncestor((node) => node is ClassMember); | 1180 staticModifier = _inStaticMemberContext2(enclosingMember); |
| 1171 // staticModifier = _inStaticMemberContext2(enclosingMember); | 1181 prefix = utils.getNodePrefix(enclosingMember); |
| 1172 // prefix = utils.getNodePrefix(enclosingMember); | 1182 insertOffset = enclosingMember.end; |
| 1173 // insertOffset = enclosingMember.end; | 1183 sourcePrefix = "${eol}${prefix}${eol}"; |
| 1174 // sourcePrefix = "${eol}${prefix}${eol}"; | 1184 sourceSuffix = ""; |
| 1175 // sourceSuffix = ""; | 1185 } else { |
| 1176 // } else { | 1186 // prepare target interface type |
| 1177 // // prepare target interface type | 1187 DartType targetType = target.bestType; |
| 1178 // DartType targetType = target.bestType; | 1188 if (targetType is! InterfaceType) { |
| 1179 // if (targetType is! InterfaceType) { | 1189 return; |
| 1180 // return; | 1190 } |
| 1181 // } | 1191 ClassElement targetElement = targetType.element as ClassElement; |
| 1182 // ClassElement targetElement = targetType.element as ClassElement; | 1192 targetSource = targetElement.source; |
| 1183 // targetSource = targetElement.source; | 1193 // may be static |
| 1184 // // may be static | 1194 if (target is Identifier) { |
| 1185 // if (target is Identifier) { | 1195 staticModifier = target.bestElement.kind == ElementKind.CLASS; |
| 1186 // staticModifier = target.bestElement.kind == ElementKind.CLASS; | 1196 } |
| 1187 // } | 1197 // prepare insert offset |
| 1188 // // prepare insert offset | 1198 ClassDeclaration targetClass = targetElement.node; |
| 1189 // ClassDeclaration targetClass = targetElement.node; | 1199 prefix = " "; |
| 1190 // prefix = " "; | 1200 insertOffset = targetClass.end - 1; |
| 1191 // insertOffset = targetClass.end - 1; | 1201 if (targetClass.members.isEmpty) { |
| 1192 // if (targetClass.members.isEmpty) { | 1202 sourcePrefix = ""; |
| 1193 // sourcePrefix = ""; | 1203 } else { |
| 1194 // } else { | 1204 sourcePrefix = "${prefix}${eol}"; |
| 1195 // sourcePrefix = "${prefix}${eol}"; | 1205 } |
| 1196 // } | 1206 sourceSuffix = eol; |
| 1197 // sourceSuffix = eol; | 1207 } |
| 1198 // } | 1208 String targetFile = targetSource.fullName; |
| 1199 // // build method source | 1209 // build method source |
| 1200 // SourceBuilder sb = new SourceBuilder.con1(insertOffset); | 1210 SourceBuilder sb = new SourceBuilder(targetFile, insertOffset); |
| 1201 // { | 1211 { |
| 1202 // sb.append(sourcePrefix); | 1212 sb.append(sourcePrefix); |
| 1203 // sb.append(prefix); | 1213 sb.append(prefix); |
| 1204 // // may be "static" | 1214 // may be "static" |
| 1205 // if (staticModifier) { | 1215 if (staticModifier) { |
| 1206 // sb.append("static "); | 1216 sb.append("static "); |
| 1207 // } | 1217 } |
| 1208 // // may be return type | 1218 // may be return type |
| 1209 // { | 1219 { |
| 1210 // DartType type = | 1220 DartType type = |
| 1211 // _addFix_undefinedMethod_create_getReturnType(invocation); | 1221 _addFix_undefinedMethod_create_getReturnType(invocation); |
| 1212 // if (type != null) { | 1222 if (type != null) { |
| 1213 // String typeSource = utils.getTypeSource2(type); | 1223 String typeSource = utils.getTypeSource(type); |
| 1214 // if (typeSource != "dynamic") { | 1224 if (typeSource != "dynamic") { |
|
Paul Berry
2014/07/25 00:28:46
It seems weird that we use a string comparison her
scheglov
2014/07/25 03:20:50
Done.
| |
| 1215 // sb.startPosition("RETURN_TYPE"); | 1225 sb.startPosition("RETURN_TYPE"); |
| 1216 // sb.append(typeSource); | 1226 sb.append(typeSource); |
| 1217 // sb.endPosition(); | 1227 sb.endPosition(); |
| 1218 // sb.append(" "); | 1228 sb.append(" "); |
| 1219 // } | 1229 } |
| 1220 // } | 1230 } |
| 1221 // } | 1231 } |
| 1222 // // append name | 1232 // append name |
| 1223 // { | 1233 { |
| 1224 // sb.startPosition("NAME"); | 1234 sb.startPosition("NAME"); |
| 1225 // sb.append(name); | 1235 sb.append(name); |
| 1226 // sb.endPosition(); | 1236 sb.endPosition(); |
| 1227 // } | 1237 } |
| 1228 // _addFix_undefinedMethod_create_parameters(sb, invocation.argumentList) ; | 1238 _addFix_undefinedMethod_create_parameters(sb, invocation.argumentList); |
| 1229 // sb.append(") {${eol}${prefix}}"); | 1239 sb.append(") {${eol}${prefix}}"); |
| 1230 // sb.append(sourceSuffix); | 1240 sb.append(sourceSuffix); |
| 1231 // } | 1241 } |
| 1232 // // insert source | 1242 // insert source |
| 1233 // _addInsertEdit(insertOffset, sb.toString()); | 1243 _insertBuilder(sb); |
| 1234 // // add linked positions | 1244 // add linked positions |
| 1235 // if (targetSource == _source) { | 1245 if (targetSource == source) { |
| 1236 // _addLinkedPosition("NAME", sb, SourceRangeFactory.rangeNode(node)); | 1246 _addLinkedPosition3('NAME', sb, rf.rangeNode(node)); |
| 1237 // } | 1247 } |
| 1238 // _addLinkedPositions(sb); | 1248 // add proposal |
| 1239 // // add proposal | 1249 _addFix(FixKind.CREATE_METHOD, [name], fixFile: targetFile); |
| 1240 // _addUnitCorrectionProposal2( | 1250 } |
| 1241 // targetSource, | |
| 1242 // FixKind.CREATE_METHOD, | |
| 1243 // [name]); | |
| 1244 // } | |
| 1245 } | 1251 } |
| 1246 | 1252 |
| 1247 /** | 1253 /** |
| 1248 * @return the possible return [Type], may be <code>null</code> if can not be identified. | 1254 * @return the possible return [Type], may be <code>null</code> if can not be identified. |
| 1249 */ | 1255 */ |
| 1250 DartType | 1256 DartType |
| 1251 _addFix_undefinedMethod_create_getReturnType(MethodInvocation invocation) { | 1257 _addFix_undefinedMethod_create_getReturnType(MethodInvocation invocation) { |
| 1252 // TODO(scheglov) implement | 1258 AstNode parent = invocation.parent; |
| 1253 // AstNode parent = invocation.parent; | 1259 // myFunction(); |
| 1254 // // myFunction(); | 1260 if (parent is ExpressionStatement) { |
| 1255 // if (parent is ExpressionStatement) { | 1261 return VoidTypeImpl.instance; |
| 1256 // return VoidTypeImpl.instance; | 1262 } |
| 1257 // } | 1263 // return myFunction(); |
| 1258 // // return myFunction(); | 1264 if (parent is ReturnStatement) { |
| 1259 // if (parent is ReturnStatement) { | 1265 ExecutableElement executable = getEnclosingExecutableElement(invocation); |
| 1260 // ExecutableElement executable = | 1266 return executable != null ? executable.returnType : null; |
| 1261 // CorrectionUtils.getEnclosingExecutableElement(invocation); | 1267 } |
| 1262 // return executable != null ? executable.returnType : null; | 1268 // int v = myFunction(); |
| 1263 // } | 1269 if (parent is VariableDeclaration) { |
| 1264 // // int v = myFunction(); | 1270 VariableDeclaration variableDeclaration = parent; |
| 1265 // if (parent is VariableDeclaration) { | 1271 if (identical(variableDeclaration.initializer, invocation)) { |
| 1266 // VariableDeclaration variableDeclaration = parent; | 1272 VariableElement variableElement = variableDeclaration.element; |
| 1267 // if (identical(variableDeclaration.initializer, invocation)) { | 1273 if (variableElement != null) { |
| 1268 // VariableElement variableElement = variableDeclaration.element; | 1274 return variableElement.type; |
| 1269 // if (variableElement != null) { | 1275 } |
| 1270 // return variableElement.type; | 1276 } |
| 1271 // } | 1277 } |
| 1272 // } | 1278 // v = myFunction(); |
| 1273 // } | 1279 if (parent is AssignmentExpression) { |
| 1274 // // v = myFunction(); | 1280 AssignmentExpression assignment = parent; |
| 1275 // if (parent is AssignmentExpression) { | 1281 if (identical(assignment.rightHandSide, invocation)) { |
| 1276 // AssignmentExpression assignment = parent; | 1282 if (assignment.operator.type == TokenType.EQ) { |
| 1277 // if (identical(assignment.rightHandSide, invocation)) { | 1283 // v = myFunction(); |
| 1278 // if (assignment.operator.type == TokenType.EQ) { | 1284 Expression lhs = assignment.leftHandSide; |
| 1279 // // v = myFunction(); | 1285 if (lhs != null) { |
| 1280 // Expression lhs = assignment.leftHandSide; | 1286 return lhs.bestType; |
| 1281 // if (lhs != null) { | 1287 } |
| 1282 // return lhs.bestType; | 1288 } else { |
| 1283 // } | 1289 // v += myFunction(); |
| 1284 // } else { | 1290 MethodElement method = assignment.bestElement; |
| 1285 // // v += myFunction(); | 1291 if (method != null) { |
| 1286 // MethodElement method = assignment.bestElement; | 1292 List<ParameterElement> parameters = method.parameters; |
| 1287 // if (method != null) { | 1293 if (parameters.length == 1) { |
| 1288 // List<ParameterElement> parameters = method.parameters; | 1294 return parameters[0].type; |
| 1289 // if (parameters.length == 1) { | 1295 } |
| 1290 // return parameters[0].type; | 1296 } |
| 1291 // } | 1297 } |
| 1292 // } | 1298 } |
| 1293 // } | 1299 } |
| 1294 // } | 1300 // v + myFunction(); |
| 1295 // } | 1301 if (parent is BinaryExpression) { |
| 1296 // // v + myFunction(); | 1302 BinaryExpression binary = parent; |
| 1297 // if (parent is BinaryExpression) { | 1303 MethodElement method = binary.bestElement; |
| 1298 // BinaryExpression binary = parent; | 1304 if (method != null) { |
| 1299 // MethodElement method = binary.bestElement; | 1305 if (identical(binary.rightOperand, invocation)) { |
| 1300 // if (method != null) { | 1306 List<ParameterElement> parameters = method.parameters; |
| 1301 // if (identical(binary.rightOperand, invocation)) { | 1307 return parameters.length == 1 ? parameters[0].type : null; |
| 1302 // List<ParameterElement> parameters = method.parameters; | 1308 } |
| 1303 // return parameters.length == 1 ? parameters[0].type : null; | 1309 } |
| 1304 // } | 1310 } |
| 1305 // } | 1311 // foo( myFunction() ); |
| 1306 // } | 1312 if (parent is ArgumentList) { |
| 1307 // // foo( myFunction() ); | 1313 ParameterElement parameter = invocation.bestParameterElement; |
| 1308 // if (parent is ArgumentList) { | 1314 return parameter != null ? parameter.type : null; |
| 1309 // ParameterElement parameter = invocation.bestParameterElement; | 1315 } |
| 1310 // return parameter != null ? parameter.type : null; | 1316 // bool |
| 1311 // } | 1317 { |
| 1312 // // bool | 1318 // assert( myFunction() ); |
| 1313 // { | 1319 if (parent is AssertStatement) { |
| 1314 // // assert( myFunction() ); | 1320 AssertStatement statement = parent; |
| 1315 // if (parent is AssertStatement) { | 1321 if (identical(statement.condition, invocation)) { |
| 1316 // AssertStatement statement = parent; | 1322 return coreTypeBool; |
| 1317 // if (identical(statement.condition, invocation)) { | 1323 } |
| 1318 // return coreTypeBool; | 1324 } |
| 1319 // } | 1325 // if ( myFunction() ) {} |
| 1320 // } | 1326 if (parent is IfStatement) { |
| 1321 // // if ( myFunction() ) {} | 1327 IfStatement statement = parent; |
| 1322 // if (parent is IfStatement) { | 1328 if (identical(statement.condition, invocation)) { |
| 1323 // IfStatement statement = parent; | 1329 return coreTypeBool; |
| 1324 // if (identical(statement.condition, invocation)) { | 1330 } |
| 1325 // return coreTypeBool; | 1331 } |
| 1326 // } | 1332 // while ( myFunction() ) {} |
| 1327 // } | 1333 if (parent is WhileStatement) { |
| 1328 // // while ( myFunction() ) {} | 1334 WhileStatement statement = parent; |
| 1329 // if (parent is WhileStatement) { | 1335 if (identical(statement.condition, invocation)) { |
| 1330 // WhileStatement statement = parent; | 1336 return coreTypeBool; |
| 1331 // if (identical(statement.condition, invocation)) { | 1337 } |
| 1332 // return coreTypeBool; | 1338 } |
| 1333 // } | 1339 // do {} while ( myFunction() ); |
| 1334 // } | 1340 if (parent is DoStatement) { |
| 1335 // // do {} while ( myFunction() ); | 1341 DoStatement statement = parent; |
| 1336 // if (parent is DoStatement) { | 1342 if (identical(statement.condition, invocation)) { |
| 1337 // DoStatement statement = parent; | 1343 return coreTypeBool; |
| 1338 // if (identical(statement.condition, invocation)) { | 1344 } |
| 1339 // return coreTypeBool; | 1345 } |
| 1340 // } | 1346 // !myFunction() |
| 1341 // } | 1347 if (parent is PrefixExpression) { |
| 1342 // // !myFunction() | 1348 PrefixExpression prefixExpression = parent; |
| 1343 // if (parent is PrefixExpression) { | 1349 if (prefixExpression.operator.type == TokenType.BANG) { |
| 1344 // PrefixExpression prefixExpression = parent; | 1350 return coreTypeBool; |
| 1345 // if (prefixExpression.operator.type == TokenType.BANG) { | 1351 } |
| 1346 // return coreTypeBool; | 1352 } |
| 1347 // } | 1353 // binary expression '&&' or '||' |
| 1348 // } | 1354 if (parent is BinaryExpression) { |
| 1349 // // binary expression '&&' or '||' | 1355 BinaryExpression binaryExpression = parent; |
| 1350 // if (parent is BinaryExpression) { | 1356 TokenType operatorType = binaryExpression.operator.type; |
| 1351 // BinaryExpression binaryExpression = parent; | 1357 if (operatorType == TokenType.AMPERSAND_AMPERSAND || |
| 1352 // TokenType operatorType = binaryExpression.operator.type; | 1358 operatorType == TokenType.BAR_BAR) { |
| 1353 // if (operatorType == TokenType.AMPERSAND_AMPERSAND || | 1359 return coreTypeBool; |
| 1354 // operatorType == TokenType.BAR_BAR) { | 1360 } |
| 1355 // return coreTypeBool; | 1361 } |
| 1356 // } | 1362 } |
| 1357 // } | |
| 1358 // } | |
| 1359 // we don't know | 1363 // we don't know |
| 1360 return null; | 1364 return null; |
| 1361 } | 1365 } |
| 1362 | 1366 |
| 1363 void _addFix_undefinedMethod_create_parameters(SourceBuilder sb, | 1367 void _addFix_undefinedMethod_create_parameters(SourceBuilder sb, |
| 1364 ArgumentList argumentList) { | 1368 ArgumentList argumentList) { |
| 1365 // append parameters | 1369 // append parameters |
| 1366 sb.append("("); | 1370 sb.append("("); |
| 1367 Set<String> excluded = new Set(); | 1371 Set<String> excluded = new Set(); |
| 1368 List<Expression> arguments = argumentList.arguments; | 1372 List<Expression> arguments = argumentList.arguments; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1510 void _addLinkedPosition2(String groupId, Position position) { | 1514 void _addLinkedPosition2(String groupId, Position position) { |
| 1511 LinkedPositionGroup group = linkedPositionGroups[groupId]; | 1515 LinkedPositionGroup group = linkedPositionGroups[groupId]; |
| 1512 if (group == null) { | 1516 if (group == null) { |
| 1513 group = new LinkedPositionGroup(groupId); | 1517 group = new LinkedPositionGroup(groupId); |
| 1514 linkedPositionGroups[groupId] = group; | 1518 linkedPositionGroups[groupId] = group; |
| 1515 } | 1519 } |
| 1516 group.add(position); | 1520 group.add(position); |
| 1517 } | 1521 } |
| 1518 | 1522 |
| 1519 /** | 1523 /** |
| 1524 * Adds a single linked position to [groupId]. | |
| 1525 */ | |
| 1526 void _addLinkedPosition3(String groupId, SourceBuilder sb, | |
| 1527 SourceRange range) { | |
| 1528 if (sb.offset < range.offset) { | |
| 1529 int delta = sb.length; | |
| 1530 range = range.getTranslated(delta); | |
| 1531 } | |
| 1532 _addLinkedPosition(groupId, range); | |
| 1533 } | |
| 1534 | |
| 1535 /** | |
| 1536 * Prepares proposal for creating function corresponding to the given [Functio nType]. | |
| 1537 */ | |
| 1538 void _addProposal_createFunction(FunctionType functionType, String name, | |
|
Paul Berry
2014/07/25 00:28:46
It seems like there's a lot in common between this
| |
| 1539 Source targetSource, int insertOffset, bool isStatic, String eol, String p refix, | |
| 1540 String sourcePrefix, String sourceSuffix) { | |
| 1541 // build method source | |
| 1542 String targetFile = targetSource.fullName; | |
| 1543 SourceBuilder sb = new SourceBuilder(targetFile, insertOffset); | |
| 1544 { | |
| 1545 sb.append(sourcePrefix); | |
| 1546 sb.append(prefix); | |
| 1547 // may be static | |
| 1548 if (isStatic) { | |
| 1549 sb.append("static "); | |
| 1550 } | |
| 1551 // may be return type | |
| 1552 { | |
| 1553 DartType returnType = functionType.returnType; | |
| 1554 if (returnType != null) { | |
| 1555 String typeSource = utils.getTypeSource(returnType); | |
| 1556 if (typeSource != "dynamic") { | |
|
Paul Berry
2014/07/25 00:28:46
Use returnType.isDynamic here too.
scheglov
2014/07/25 03:20:50
Done.
| |
| 1557 sb.startPosition("RETURN_TYPE"); | |
| 1558 sb.append(typeSource); | |
| 1559 sb.endPosition(); | |
| 1560 sb.append(" "); | |
| 1561 } | |
| 1562 } | |
| 1563 } | |
| 1564 // append name | |
| 1565 { | |
| 1566 sb.startPosition("NAME"); | |
| 1567 sb.append(name); | |
| 1568 sb.endPosition(); | |
| 1569 } | |
| 1570 // append parameters | |
| 1571 sb.append("("); | |
| 1572 List<ParameterElement> parameters = functionType.parameters; | |
| 1573 for (int i = 0; i < parameters.length; i++) { | |
| 1574 ParameterElement parameter = parameters[i]; | |
| 1575 // append separator | |
| 1576 if (i != 0) { | |
| 1577 sb.append(", "); | |
| 1578 } | |
| 1579 // append type name | |
| 1580 DartType type = parameter.type; | |
| 1581 String typeSource = utils.getTypeSource(type); | |
| 1582 { | |
|
Paul Berry
2014/07/25 00:28:45
Should we guard this with "if (!type.isDynamic)",
scheglov
2014/07/25 03:20:50
Done.
I've also added a test.
| |
| 1583 sb.startPosition("TYPE${i}"); | |
| 1584 sb.append(typeSource); | |
| 1585 _addSuperTypeProposals(sb, new Set(), type); | |
| 1586 sb.endPosition(); | |
| 1587 } | |
| 1588 sb.append(" "); | |
| 1589 // append parameter name | |
| 1590 { | |
| 1591 sb.startPosition("ARG${i}"); | |
| 1592 sb.append(parameter.displayName); | |
| 1593 sb.endPosition(); | |
| 1594 } | |
| 1595 } | |
| 1596 sb.append(")"); | |
| 1597 // close method | |
| 1598 sb.append(" {${eol}${prefix}}"); | |
|
Paul Berry
2014/07/25 00:28:46
Space before $eol seems unnecessary.
scheglov
2014/07/25 03:20:50
The space is before "{", which opens the body bloc
| |
| 1599 sb.append(sourceSuffix); | |
| 1600 } | |
| 1601 // insert source | |
| 1602 _insertBuilder(sb); | |
| 1603 // add linked positions | |
| 1604 if (targetSource == source) { | |
| 1605 _addLinkedPosition3("NAME", sb, rf.rangeNode(node)); | |
| 1606 } | |
| 1607 } | |
| 1608 | |
| 1609 /** | |
| 1610 * Adds proposal for creating method corresponding to the given [FunctionType] in the given | |
| 1611 * [ClassElement]. | |
| 1612 */ | |
| 1613 void _addProposal_createFunction_function(FunctionType functionType) { | |
| 1614 String name = (node as SimpleIdentifier).name; | |
| 1615 // prepare environment | |
| 1616 String eol = utils.endOfLine; | |
| 1617 int insertOffset = unit.end; | |
| 1618 // prepare prefix | |
| 1619 String prefix = ""; | |
| 1620 String sourcePrefix = "${eol}"; | |
| 1621 String sourceSuffix = eol; | |
| 1622 _addProposal_createFunction( | |
| 1623 functionType, | |
| 1624 name, | |
| 1625 source, | |
| 1626 insertOffset, | |
| 1627 false, | |
| 1628 eol, | |
| 1629 prefix, | |
| 1630 sourcePrefix, | |
| 1631 sourceSuffix); | |
| 1632 // add proposal | |
| 1633 _addFix(FixKind.CREATE_FUNCTION, [name], fixFile: file); | |
| 1634 } | |
| 1635 | |
| 1636 /** | |
| 1637 * Adds proposal for creating method corresponding to the given [FunctionType] in the given | |
| 1638 * [ClassElement]. | |
| 1639 */ | |
| 1640 void _addProposal_createFunction_method(ClassElement targetClassElement, | |
| 1641 FunctionType functionType) { | |
| 1642 String name = (node as SimpleIdentifier).name; | |
| 1643 // prepare environment | |
| 1644 String eol = utils.endOfLine; | |
|
Paul Berry
2014/07/25 00:28:45
Suggestion: rather than force the caller to look u
scheglov
2014/07/25 03:20:50
Done.
| |
| 1645 Source targetSource = targetClassElement.source; | |
| 1646 String targetFile = targetSource.fullName; | |
| 1647 // prepare insert offset | |
| 1648 ClassDeclaration targetClassNode = targetClassElement.node; | |
| 1649 int insertOffset = targetClassNode.end - 1; | |
| 1650 // prepare prefix | |
| 1651 String prefix = " "; | |
| 1652 String sourcePrefix; | |
| 1653 if (targetClassNode.members.isEmpty) { | |
| 1654 sourcePrefix = ""; | |
| 1655 } else { | |
| 1656 sourcePrefix = "${prefix}${eol}"; | |
|
Paul Berry
2014/07/25 00:28:45
This will just insert a blank line containing whit
scheglov
2014/07/25 03:20:51
Done.
| |
| 1657 } | |
| 1658 String sourceSuffix = eol; | |
| 1659 _addProposal_createFunction( | |
| 1660 functionType, | |
| 1661 name, | |
| 1662 targetSource, | |
| 1663 insertOffset, | |
| 1664 _inStaticMemberContext(), | |
| 1665 eol, | |
| 1666 prefix, | |
| 1667 sourcePrefix, | |
| 1668 sourceSuffix); | |
| 1669 // add proposal | |
| 1670 _addFix(FixKind.CREATE_METHOD, [name], fixFile: targetFile); | |
| 1671 } | |
| 1672 | |
| 1673 /** | |
| 1520 * Adds a new [Edit] to [edits]. | 1674 * Adds a new [Edit] to [edits]. |
| 1521 */ | 1675 */ |
| 1522 void _addRemoveEdit(SourceRange range) { | 1676 void _addRemoveEdit(SourceRange range) { |
| 1523 _addReplaceEdit(range, ''); | 1677 _addReplaceEdit(range, ''); |
| 1524 } | 1678 } |
| 1525 | 1679 |
| 1526 /** | 1680 /** |
| 1527 * Adds a new [Edit] to [edits]. | 1681 * Adds a new [Edit] to [edits]. |
| 1528 */ | 1682 */ |
| 1529 void _addReplaceEdit(SourceRange range, String text) { | 1683 void _addReplaceEdit(SourceRange range, String text) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1580 // close parameters | 1734 // close parameters |
| 1581 if (sawNamed) { | 1735 if (sawNamed) { |
| 1582 sb.write("}"); | 1736 sb.write("}"); |
| 1583 } | 1737 } |
| 1584 if (sawPositional) { | 1738 if (sawPositional) { |
| 1585 sb.write("]"); | 1739 sb.write("]"); |
| 1586 } | 1740 } |
| 1587 sb.write(")"); | 1741 sb.write(")"); |
| 1588 } | 1742 } |
| 1589 | 1743 |
| 1590 // void _addLinkedPositionProposal(String group, | 1744 void _appendType(StringBuffer sb, DartType type) { |
| 1591 // LinkedPositionProposal proposal) { | 1745 if (type != null && !type.isDynamic) { |
| 1592 // List<LinkedPositionProposal> nodeProposals = linkedPositionProposals[group ]; | 1746 String typeSource = utils.getTypeSource(type); |
| 1593 // if (nodeProposals == null) { | 1747 sb.write(typeSource); |
| 1594 // nodeProposals = <LinkedPositionProposal>[]; | 1748 sb.write(' '); |
| 1595 // linkedPositionProposals[group] = nodeProposals; | 1749 } |
| 1596 // } | 1750 } |
| 1597 // nodeProposals.add(proposal); | |
| 1598 // } | |
| 1599 | 1751 |
| 1600 /** | 1752 /** |
| 1601 * @return the string to display as the name of the given constructor in a pro posal name. | 1753 * @return the string to display as the name of the given constructor in a pro posal name. |
| 1602 */ | 1754 */ |
| 1603 String _getConstructorProposalName(ConstructorElement constructor) { | 1755 String _getConstructorProposalName(ConstructorElement constructor) { |
| 1604 StringBuffer proposalNameBuffer = new StringBuffer(); | 1756 StringBuffer proposalNameBuffer = new StringBuffer(); |
| 1605 proposalNameBuffer.write("super"); | 1757 proposalNameBuffer.write("super"); |
| 1606 // may be named | 1758 // may be named |
| 1607 String constructorName = constructor.displayName; | 1759 String constructorName = constructor.displayName; |
| 1608 if (!constructorName.isEmpty) { | 1760 if (!constructorName.isEmpty) { |
| 1609 proposalNameBuffer.write("."); | 1761 proposalNameBuffer.write("."); |
| 1610 proposalNameBuffer.write(constructorName); | 1762 proposalNameBuffer.write(constructorName); |
| 1611 } | 1763 } |
| 1612 // parameters | 1764 // parameters |
| 1613 _appendParameters(proposalNameBuffer, constructor.parameters, null); | 1765 _appendParameters(proposalNameBuffer, constructor.parameters, null); |
| 1614 // done | 1766 // done |
| 1615 return proposalNameBuffer.toString(); | 1767 return proposalNameBuffer.toString(); |
| 1616 } | 1768 } |
| 1617 | 1769 |
| 1618 /** | 1770 /** |
| 1771 * Returns the [Type] with given name from the `dart:core` library. | |
| 1772 */ | |
| 1773 DartType _getCoreType(String name) { | |
| 1774 List<LibraryElement> libraries = unitLibraryElement.importedLibraries; | |
| 1775 for (LibraryElement library in libraries) { | |
| 1776 if (library.isDartCore) { | |
| 1777 ClassElement classElement = library.getType(name); | |
| 1778 if (classElement != null) { | |
| 1779 return classElement.type; | |
| 1780 } | |
| 1781 return null; | |
| 1782 } | |
| 1783 } | |
| 1784 return null; | |
| 1785 } | |
| 1786 | |
| 1787 Map<ParameterElement, String> | |
| 1788 _getDefaultValueMap(List<ParameterElement> parameters) { | |
| 1789 Map<ParameterElement, String> defaultSourceMap = {}; | |
| 1790 Map<Source, String> sourceContentMap = {}; | |
| 1791 for (ParameterElement parameter in parameters) { | |
| 1792 SourceRange valueRange = parameter.defaultValueRange; | |
| 1793 if (valueRange != null) { | |
| 1794 Source source = parameter.source; | |
| 1795 String sourceContent = sourceContentMap[source]; | |
| 1796 if (sourceContent == null) { | |
| 1797 sourceContent = getSourceContent(parameter.context, source); | |
| 1798 sourceContentMap[source] = sourceContent; | |
| 1799 } | |
| 1800 String valueSource = | |
| 1801 sourceContent.substring(valueRange.offset, valueRange.end); | |
| 1802 defaultSourceMap[parameter] = valueSource; | |
| 1803 } | |
| 1804 } | |
| 1805 return defaultSourceMap; | |
| 1806 } | |
| 1807 | |
| 1808 /** | |
| 1809 * Returns `true` if [node] if part of a static method or of a field | |
| 1810 * initializer. | |
| 1811 */ | |
| 1812 bool _inStaticMemberContext() { | |
|
Paul Berry
2014/07/25 00:28:45
This won't do the right thing if node is in a cons
scheglov
2014/07/25 03:20:50
Added the test and fixed.
| |
| 1813 ClassMember member = node.getAncestor((node) => node is ClassMember); | |
| 1814 return _inStaticMemberContext2(member); | |
|
Paul Berry
2014/07/25 00:28:45
Rather than having two functions and forcing the c
scheglov
2014/07/25 03:20:51
Done.
| |
| 1815 } | |
| 1816 | |
| 1817 // void _addLinkedPositionProposal(String group, | |
| 1818 // LinkedPositionProposal proposal) { | |
| 1819 // List<LinkedPositionProposal> nodeProposals = linkedPositionProposals[group ]; | |
| 1820 // if (nodeProposals == null) { | |
| 1821 // nodeProposals = <LinkedPositionProposal>[]; | |
| 1822 // linkedPositionProposals[group] = nodeProposals; | |
| 1823 // } | |
| 1824 // nodeProposals.add(proposal); | |
| 1825 // } | |
| 1826 | |
| 1827 /** | |
| 1828 * Returns `true` if the given [ClassMember] is a part of a static method or | |
| 1829 * a field initializer. | |
| 1830 */ | |
| 1831 bool _inStaticMemberContext2(ClassMember member) { | |
| 1832 if (member is MethodDeclaration) { | |
| 1833 return member.isStatic; | |
| 1834 } | |
| 1835 // field initializer cannot reference "this" | |
| 1836 if (member is FieldDeclaration) { | |
| 1837 return true; | |
| 1838 } | |
| 1839 return false; | |
| 1840 } | |
| 1841 | |
| 1842 /** | |
| 1619 * Inserts the given [SourceBuilder] at its offset. | 1843 * Inserts the given [SourceBuilder] at its offset. |
| 1620 */ | 1844 */ |
| 1621 void _insertBuilder(SourceBuilder builder) { | 1845 void _insertBuilder(SourceBuilder builder) { |
| 1622 String text = builder.toString(); | 1846 String text = builder.toString(); |
| 1623 _addInsertEdit(builder.offset, text); | 1847 _addInsertEdit(builder.offset, text); |
| 1624 // add linked positions | 1848 // add linked positions |
| 1625 builder.linkedPositionGroups.forEach((LinkedPositionGroup group) { | 1849 builder.linkedPositionGroups.forEach((LinkedPositionGroup group) { |
| 1626 group.positions.forEach((Position position) { | 1850 group.positions.forEach((Position position) { |
| 1627 _addLinkedPosition2(group.id, position); | 1851 _addLinkedPosition2(group.id, position); |
| 1628 }); | 1852 }); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1729 * TODO(scheglov) rename | 1953 * TODO(scheglov) rename |
| 1730 */ | 1954 */ |
| 1731 class QuickFixProcessorImpl_NewConstructorLocation { | 1955 class QuickFixProcessorImpl_NewConstructorLocation { |
| 1732 final String _prefix; | 1956 final String _prefix; |
| 1733 final int _offset; | 1957 final int _offset; |
| 1734 final String _suffix; | 1958 final String _suffix; |
| 1735 | 1959 |
| 1736 QuickFixProcessorImpl_NewConstructorLocation(this._prefix, this._offset, | 1960 QuickFixProcessorImpl_NewConstructorLocation(this._prefix, this._offset, |
| 1737 this._suffix); | 1961 this._suffix); |
| 1738 } | 1962 } |
| OLD | NEW |