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 |