Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Side by Side Diff: pkg/analysis_services/lib/src/correction/fix.dart

Issue 418203002: Implement more fixes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixes for review comments Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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");
61
62 /**
63 * Returns the EOL to use for this [CompilationUnit].
64 */
65 String get eol => utils.endOfLine;
49 66
50 List<Fix> compute() { 67 List<Fix> compute() {
51 utils = new CorrectionUtils(unit); 68 utils = new CorrectionUtils(unit);
52 errorOffset = error.offset; 69 errorOffset = error.offset;
53 errorLength = error.length; 70 errorLength = error.length;
54 errorEnd = errorOffset + errorLength; 71 errorEnd = errorOffset + errorLength;
55 node = new NodeLocator.con1(errorOffset).searchWithin(unit); 72 node = new NodeLocator.con1(errorOffset).searchWithin(unit);
56 coveredNode = new NodeLocator.con2( 73 coveredNode = new NodeLocator.con2(
57 errorOffset, 74 errorOffset,
58 errorOffset + errorLength).searchWithin(unit); 75 errorOffset + errorLength).searchWithin(unit);
59 // analyze ErrorCode 76 // analyze ErrorCode
60 ErrorCode errorCode = error.errorCode; 77 ErrorCode errorCode = error.errorCode;
61 if (errorCode == StaticWarningCode.UNDEFINED_CLASS_BOOLEAN) { 78 if (errorCode == StaticWarningCode.UNDEFINED_CLASS_BOOLEAN) {
62 _addFix_boolInsteadOfBoolean(); 79 _addFix_boolInsteadOfBoolean();
63 } 80 }
64 if (errorCode == 81 if (errorCode ==
65 CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE) { 82 CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE) {
66 _addFix_replaceWithConstInstanceCreation(); 83 _addFix_replaceWithConstInstanceCreation();
67 } 84 }
68 if (errorCode == 85 if (errorCode ==
69 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT) { 86 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT) {
70 _addFix_createConstructorSuperExplicit(); 87 _addFix_createConstructorSuperExplicit();
71 } 88 }
72 // if (identical( 89 if (errorCode ==
73 // errorCode, 90 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT) {
74 // CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT)) { 91 _addFix_createConstructorSuperImplicit();
75 // _addFix_createConstructorSuperImplicit(); 92 }
76 // }
77 if (errorCode == 93 if (errorCode ==
78 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT) { 94 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT) {
79 _addFix_createConstructorSuperExplicit(); 95 _addFix_createConstructorSuperExplicit();
80 } 96 }
81 // if (identical(errorCode, CompileTimeErrorCode.URI_DOES_NOT_EXIST)) { 97 // if (identical(errorCode, CompileTimeErrorCode.URI_DOES_NOT_EXIST)) {
82 // _addFix_createPart(); 98 // _addFix_createPart();
83 // _addFix_addPackageDependency(); 99 // _addFix_addPackageDependency();
84 // } 100 // }
85 if (errorCode == HintCode.DIVISION_OPTIMIZATION) { 101 if (errorCode == HintCode.DIVISION_OPTIMIZATION) {
86 _addFix_useEffectiveIntegerDivision(); 102 _addFix_useEffectiveIntegerDivision();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 List<ExecutableElement> missingOverrides = 148 List<ExecutableElement> missingOverrides =
133 property as List<ExecutableElement>; 149 property as List<ExecutableElement>;
134 _addFix_createMissingOverrides(missingOverrides); 150 _addFix_createMissingOverrides(missingOverrides);
135 _addFix_createNoSuchMethod(); 151 _addFix_createNoSuchMethod();
136 } 152 }
137 if (errorCode == StaticWarningCode.UNDEFINED_CLASS) { 153 if (errorCode == StaticWarningCode.UNDEFINED_CLASS) {
138 _addFix_importLibrary_withType(); 154 _addFix_importLibrary_withType();
139 _addFix_createClass(); 155 _addFix_createClass();
140 _addFix_undefinedClass_useSimilar(); 156 _addFix_undefinedClass_useSimilar();
141 } 157 }
142 // if (identical(errorCode, StaticWarningCode.UNDEFINED_IDENTIFIER)) { 158 if (errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER) {
143 // _addFix_createFunction_forFunctionType(); 159 _addFix_createFunction_forFunctionType();
144 // _addFix_importLibrary_withType(); 160 _addFix_importLibrary_withType();
145 // _addFix_importLibrary_withTopLevelVariable(); 161 _addFix_importLibrary_withTopLevelVariable();
146 // } 162 }
147 if (errorCode == StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER) { 163 if (errorCode == StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER) {
148 _addFix_useStaticAccess_method(); 164 _addFix_useStaticAccess_method();
149 _addFix_useStaticAccess_property(); 165 _addFix_useStaticAccess_property();
150 } 166 }
151 if (errorCode == StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) { 167 if (errorCode == StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) {
152 _addFix_removeParentheses_inGetterInvocation(); 168 _addFix_removeParentheses_inGetterInvocation();
153 } 169 }
154 // if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) { 170 // if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) {
155 // _addFix_importLibrary_withFunction(); 171 // _addFix_importLibrary_withFunction();
156 // _addFix_undefinedFunction_useSimilar(); 172 // _addFix_undefinedFunction_useSimilar();
157 // _addFix_undefinedFunction_create(); 173 // _addFix_undefinedFunction_create();
158 // } 174 // }
159 // if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_GETTER)) { 175 if (errorCode == StaticTypeWarningCode.UNDEFINED_GETTER) {
160 // _addFix_createFunction_forFunctionType(); 176 _addFix_createFunction_forFunctionType();
161 // } 177 }
162 // if (identical(errorCode, HintCode.UNDEFINED_METHOD) || 178 if (errorCode == HintCode.UNDEFINED_METHOD ||
163 // identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { 179 errorCode == StaticTypeWarningCode.UNDEFINED_METHOD) {
164 // _addFix_undefinedMethod_useSimilar(); 180 _addFix_undefinedMethod_useSimilar();
165 // _addFix_undefinedMethod_create(); 181 _addFix_undefinedMethod_create();
166 // _addFix_undefinedFunction_create(); 182 _addFix_undefinedFunction_create();
167 // } 183 }
168 // done 184 // done
169 return fixes; 185 return fixes;
170 } 186 }
171 187
172 void _addFix(FixKind kind, List args, {String fixFile}) { 188 void _addFix(FixKind kind, List args, {String fixFile}) {
173 if (fixFile == null) { 189 if (fixFile == null) {
174 fixFile = file; 190 fixFile = file;
175 } 191 }
176 FileEdit fileEdit = new FileEdit(file); 192 FileEdit fileEdit = new FileEdit(file);
177 edits.forEach((edit) => fileEdit.add(edit)); 193 edits.forEach((edit) => fileEdit.add(edit));
178 // prepare Change 194 // prepare Change
179 String message = JavaString.format(kind.message, args); 195 String message = JavaString.format(kind.message, args);
180 Change change = new Change(message); 196 Change change = new Change(message);
181 change.add(fileEdit); 197 change.add(fileEdit);
182 linkedPositionGroups.values.forEach( 198 linkedPositionGroups.values.forEach(
183 (group) => change.addLinkedPositionGroup(group)); 199 (group) => change.addLinkedPositionGroup(group));
200 change.endPosition = endPosition;
184 // add Fix 201 // add Fix
185 Fix fix = new Fix(kind, change); 202 Fix fix = new Fix(kind, change);
186 fixes.add(fix); 203 fixes.add(fix);
204 // clear
205 edits.clear();
206 linkedPositionGroups.clear();
207 endPosition = null;
187 } 208 }
188 209
210
189 void _addFix_addPackageDependency() { 211 void _addFix_addPackageDependency() {
190 // TODO(scheglov) implement 212 // TODO(scheglov) implement
191 // if (node is SimpleStringLiteral && node.parent is NamespaceDirective) { 213 // if (node is SimpleStringLiteral && node.parent is NamespaceDirective) {
192 // SimpleStringLiteral uriLiteral = node as SimpleStringLiteral; 214 // SimpleStringLiteral uriLiteral = node as SimpleStringLiteral;
193 // String uriString = uriLiteral.value; 215 // String uriString = uriLiteral.value;
194 // // we need package: import 216 // // we need package: import
195 // if (!uriString.startsWith("package:")) { 217 // if (!uriString.startsWith("package:")) {
196 // return; 218 // return;
197 // } 219 // }
198 // // prepare package name 220 // // prepare package name
199 // String packageName = StringUtils.removeStart(uriString, "package:"); 221 // String packageName = StringUtils.removeStart(uriString, "package:");
200 // packageName = StringUtils.substringBefore(packageName, "/"); 222 // packageName = StringUtils.substringBefore(packageName, "/");
201 // // add proposal 223 // // add proposal
202 // _proposals.add( 224 // _proposals.add(
203 // new AddDependencyCorrectionProposal( 225 // new AddDependencyCorrectionProposal(
204 // _unitFile, 226 // _unitFile,
205 // packageName, 227 // packageName,
206 // FixKind.ADD_PACKAGE_DEPENDENCY, 228 // FixKind.ADD_PACKAGE_DEPENDENCY,
207 // [packageName])); 229 // [packageName]));
208 // } 230 // }
209 } 231 }
210 232
233
211 void _addFix_boolInsteadOfBoolean() { 234 void _addFix_boolInsteadOfBoolean() {
212 SourceRange range = rf.rangeError(error); 235 SourceRange range = rf.rangeError(error);
213 _addReplaceEdit(range, "bool"); 236 _addReplaceEdit(range, "bool");
214 _addFix(FixKind.REPLACE_BOOLEAN_WITH_BOOL, []); 237 _addFix(FixKind.REPLACE_BOOLEAN_WITH_BOOL, []);
215 } 238 }
216 239
217
218 void _addFix_createClass() { 240 void _addFix_createClass() {
219 if (_mayBeTypeIdentifier(node)) { 241 if (_mayBeTypeIdentifier(node)) {
220 String name = (node as SimpleIdentifier).name; 242 String name = (node as SimpleIdentifier).name;
221 // prepare environment 243 // prepare environment
222 String eol = utils.endOfLine;
223 CompilationUnitMember enclosingMember = 244 CompilationUnitMember enclosingMember =
224 node.getAncestor((node) => node is CompilationUnitMember); 245 node.getAncestor((node) => node is CompilationUnitMember);
225 int offset = enclosingMember.end; 246 int offset = enclosingMember.end;
226 String prefix = ""; 247 String prefix = "";
227 // prepare source 248 // prepare source
228 SourceBuilder sb = new SourceBuilder(file, offset); 249 SourceBuilder sb = new SourceBuilder(file, offset);
229 { 250 {
230 sb.append("${eol}${eol}"); 251 sb.append("${eol}${eol}");
231 sb.append(prefix); 252 sb.append(prefix);
232 // "class" 253 // "class"
(...skipping 10 matching lines...) Expand all
243 sb.append("}"); 264 sb.append("}");
244 } 265 }
245 // insert source 266 // insert source
246 _insertBuilder(sb); 267 _insertBuilder(sb);
247 _addLinkedPosition("NAME", rf.rangeNode(node)); 268 _addLinkedPosition("NAME", rf.rangeNode(node));
248 // add proposal 269 // add proposal
249 _addFix(FixKind.CREATE_CLASS, [name]); 270 _addFix(FixKind.CREATE_CLASS, [name]);
250 } 271 }
251 } 272 }
252 273
253
254 void _addFix_createConstructorSuperExplicit() { 274 void _addFix_createConstructorSuperExplicit() {
255 ConstructorDeclaration targetConstructor = 275 ConstructorDeclaration targetConstructor =
256 node.parent as ConstructorDeclaration; 276 node.parent as ConstructorDeclaration;
257 ClassDeclaration targetClassNode = 277 ClassDeclaration targetClassNode =
258 targetConstructor.parent as ClassDeclaration; 278 targetConstructor.parent as ClassDeclaration;
259 ClassElement targetClassElement = targetClassNode.element; 279 ClassElement targetClassElement = targetClassNode.element;
260 ClassElement superClassElement = targetClassElement.supertype.element; 280 ClassElement superClassElement = targetClassElement.supertype.element;
261 // add proposals for all super constructors 281 // add proposals for all super constructors
262 List<ConstructorElement> superConstructors = superClassElement.constructors; 282 List<ConstructorElement> superConstructors = superClassElement.constructors;
263 for (ConstructorElement superConstructor in superConstructors) { 283 for (ConstructorElement superConstructor in superConstructors) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 sb.append(")"); 332 sb.append(")");
313 // insert proposal 333 // insert proposal
314 _insertBuilder(sb); 334 _insertBuilder(sb);
315 // add proposal 335 // add proposal
316 String proposalName = _getConstructorProposalName(superConstructor); 336 String proposalName = _getConstructorProposalName(superConstructor);
317 _addFix(FixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, [proposalName]); 337 _addFix(FixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, [proposalName]);
318 } 338 }
319 } 339 }
320 340
321 void _addFix_createConstructorSuperImplicit() { 341 void _addFix_createConstructorSuperImplicit() {
322 // TODO(scheglov) implement 342 ClassDeclaration targetClassNode = node.parent as ClassDeclaration;
323 // ClassDeclaration targetClassNode = node.parent as ClassDeclaration; 343 ClassElement targetClassElement = targetClassNode.element;
324 // ClassElement targetClassElement = targetClassNode.element; 344 ClassElement superClassElement = targetClassElement.supertype.element;
325 // ClassElement superClassElement = targetClassElement.supertype.element; 345 String targetClassName = targetClassElement.name;
326 // String targetClassName = targetClassElement.name; 346 // add proposals for all super constructors
327 // // add proposals for all super constructors 347 List<ConstructorElement> superConstructors = superClassElement.constructors;
328 // List<ConstructorElement> superConstructors = superClassElement.constructor s; 348 for (ConstructorElement superConstructor in superConstructors) {
329 // for (ConstructorElement superConstructor in superConstructors) { 349 String constructorName = superConstructor.name;
330 // String constructorName = superConstructor.name; 350 // skip private
331 // // skip private 351 if (Identifier.isPrivateName(constructorName)) {
332 // if (Identifier.isPrivateName(constructorName)) { 352 continue;
333 // continue; 353 }
334 // } 354 // prepare parameters and arguments
335 // // prepare parameters and arguments 355 SourceBuilder parametersBuffer = new SourceBuilder.buffer();
336 // JavaStringBuilder parametersBuffer = new JavaStringBuilder(); 356 SourceBuilder argumentsBuffer = new SourceBuilder.buffer();
337 // JavaStringBuilder argumentsBuffer = new JavaStringBuilder(); 357 bool firstParameter = true;
338 // bool firstParameter = true; 358 for (ParameterElement parameter in superConstructor.parameters) {
339 // for (ParameterElement parameter in superConstructor.parameters) { 359 // skip non-required parameters
340 // // skip non-required parameters 360 if (parameter.parameterKind != ParameterKind.REQUIRED) {
341 // if (parameter.parameterKind != ParameterKind.REQUIRED) { 361 break;
342 // break; 362 }
343 // } 363 // comma
344 // // comma 364 if (firstParameter) {
345 // if (firstParameter) { 365 firstParameter = false;
346 // firstParameter = false; 366 } else {
347 // } else { 367 parametersBuffer.append(', ');
348 // parametersBuffer.append(", "); 368 argumentsBuffer.append(', ');
349 // argumentsBuffer.append(", "); 369 }
350 // } 370 // name
351 // // name 371 String parameterName = parameter.displayName;
352 // String parameterName = parameter.displayName; 372 if (parameterName.length > 1 && parameterName.startsWith('_')) {
353 // if (parameterName.length > 1 && parameterName.startsWith("_")) { 373 parameterName = parameterName.substring(1);
354 // parameterName = parameterName.substring(1); 374 }
355 // } 375 // parameter & argument
356 // // parameter & argument 376 _appendParameterSource(parametersBuffer, parameter.type, parameterName);
357 // _appendParameterSource(parametersBuffer, parameter.type, parameterName ); 377 argumentsBuffer.append(parameterName);
358 // argumentsBuffer.append(parameterName); 378 }
359 // } 379 // add proposal
360 // // add proposal 380 _ConstructorLocation targetLocation =
361 // String eol = utils.endOfLine; 381 _prepareNewConstructorLocation(targetClassNode);
362 // QuickFixProcessorImpl_NewConstructorLocation targetLocation = 382 SourceBuilder sb = new SourceBuilder(file, targetLocation._offset);
363 // _prepareNewConstructorLocation(targetClassNode, eol); 383 {
364 // SourceBuilder sb = new SourceBuilder.con1(targetLocation._offset); 384 String indent = utils.getIndent(1);
365 // { 385 sb.append(targetLocation._prefix);
366 // String indent = utils.getIndent(1); 386 sb.append(indent);
367 // sb.append(targetLocation._prefix); 387 sb.append(targetClassName);
368 // sb.append(indent); 388 if (!constructorName.isEmpty) {
369 // sb.append(targetClassName); 389 sb.startPosition('NAME');
370 // if (!constructorName.isEmpty) { 390 sb.append('.');
371 // sb.startPosition("NAME"); 391 sb.append(constructorName);
372 // sb.append("."); 392 sb.endPosition();
373 // sb.append(constructorName); 393 }
374 // sb.endPosition(); 394 sb.append("(");
375 // } 395 sb.append(parametersBuffer.toString());
376 // sb.append("("); 396 sb.append(') : super');
377 // sb.append(parametersBuffer.toString()); 397 if (!constructorName.isEmpty) {
378 // sb.append(") : super"); 398 sb.append('.');
379 // if (!constructorName.isEmpty) { 399 sb.append(constructorName);
380 // sb.append("."); 400 }
381 // sb.append(constructorName); 401 sb.append('(');
382 // } 402 sb.append(argumentsBuffer.toString());
383 // sb.append("("); 403 sb.append(');');
384 // sb.append(argumentsBuffer.toString()); 404 sb.append(targetLocation._suffix);
385 // sb.append(");"); 405 }
386 // sb.append(targetLocation._suffix); 406 _insertBuilder(sb);
387 // } 407 // add proposal
388 // _addInsertEdit3(sb); 408 String proposalName = _getConstructorProposalName(superConstructor);
389 // // add proposal 409 _addFix(FixKind.CREATE_CONSTRUCTOR_SUPER, [proposalName]);
390 // String proposalName = _getConstructorProposalName(superConstructor); 410 }
391 // _addFix(
392 // FixKind.CREATE_CONSTRUCTOR_SUPER,
393 // [proposalName]);
394 // }
395 } 411 }
396 412
397 void _addFix_createConstructor_insteadOfSyntheticDefault() { 413 void _addFix_createConstructor_insteadOfSyntheticDefault() {
398 TypeName typeName = null; 414 TypeName typeName = null;
399 ConstructorName constructorName = null; 415 ConstructorName constructorName = null;
400 InstanceCreationExpression instanceCreation = null; 416 InstanceCreationExpression instanceCreation = null;
401 if (node is SimpleIdentifier) { 417 if (node is SimpleIdentifier) {
402 if (node.parent is TypeName) { 418 if (node.parent is TypeName) {
403 typeName = node.parent as TypeName; 419 typeName = node.parent as TypeName;
404 if (typeName.name == node && typeName.parent is ConstructorName) { 420 if (typeName.name == node && typeName.parent is ConstructorName) {
(...skipping 16 matching lines...) Expand all
421 return; 437 return;
422 } 438 }
423 } 439 }
424 } 440 }
425 } 441 }
426 } 442 }
427 // do we have enough information? 443 // do we have enough information?
428 if (instanceCreation == null) { 444 if (instanceCreation == null) {
429 return; 445 return;
430 } 446 }
431 // prepare environment
432 String eol = utils.endOfLine;
433 // prepare target 447 // prepare target
434 DartType targetType = typeName.type; 448 DartType targetType = typeName.type;
435 if (targetType is! InterfaceType) { 449 if (targetType is! InterfaceType) {
436 return; 450 return;
437 } 451 }
438 ClassElement targetElement = targetType.element as ClassElement; 452 ClassElement targetElement = targetType.element as ClassElement;
439 String targetFile = targetElement.source.fullName; 453 String targetFile = targetElement.source.fullName;
440 ClassDeclaration targetClass = targetElement.node; 454 ClassDeclaration targetClass = targetElement.node;
441 QuickFixProcessorImpl_NewConstructorLocation targetLocation = 455 _ConstructorLocation targetLocation =
442 _prepareNewConstructorLocation(targetClass, eol); 456 _prepareNewConstructorLocation(targetClass);
443 // build method source 457 // build method source
444 SourceBuilder sb = new SourceBuilder(targetFile, targetLocation._offset); 458 SourceBuilder sb = new SourceBuilder(targetFile, targetLocation._offset);
445 { 459 {
446 String indent = " "; 460 String indent = " ";
447 sb.append(targetLocation._prefix); 461 sb.append(targetLocation._prefix);
448 sb.append(indent); 462 sb.append(indent);
449 sb.append(targetElement.name); 463 sb.append(targetElement.name);
450 _addFix_undefinedMethod_create_parameters( 464 _addFix_undefinedMethod_create_parameters(
451 sb, 465 sb,
452 instanceCreation.argumentList); 466 instanceCreation.argumentList);
(...skipping 25 matching lines...) Expand all
478 return; 492 return;
479 } 493 }
480 } 494 }
481 } 495 }
482 } 496 }
483 } 497 }
484 // do we have enough information? 498 // do we have enough information?
485 if (instanceCreation == null) { 499 if (instanceCreation == null) {
486 return; 500 return;
487 } 501 }
488 // prepare environment
489 String eol = utils.endOfLine;
490 // prepare target interface type 502 // prepare target interface type
491 DartType targetType = constructorName.type.type; 503 DartType targetType = constructorName.type.type;
492 if (targetType is! InterfaceType) { 504 if (targetType is! InterfaceType) {
493 return; 505 return;
494 } 506 }
495 ClassElement targetElement = targetType.element as ClassElement; 507 ClassElement targetElement = targetType.element as ClassElement;
496 String targetFile = targetElement.source.fullName; 508 String targetFile = targetElement.source.fullName;
497 ClassDeclaration targetClass = targetElement.node; 509 ClassDeclaration targetClass = targetElement.node;
498 QuickFixProcessorImpl_NewConstructorLocation targetLocation = 510 _ConstructorLocation targetLocation =
499 _prepareNewConstructorLocation(targetClass, eol); 511 _prepareNewConstructorLocation(targetClass);
500 // build method source 512 // build method source
501 SourceBuilder sb = new SourceBuilder(targetFile, targetLocation._offset); 513 SourceBuilder sb = new SourceBuilder(targetFile, targetLocation._offset);
502 { 514 {
503 String indent = " "; 515 String indent = " ";
504 sb.append(targetLocation._prefix); 516 sb.append(targetLocation._prefix);
505 sb.append(indent); 517 sb.append(indent);
506 sb.append(targetElement.name); 518 sb.append(targetElement.name);
507 sb.append("."); 519 sb.append(".");
508 // append name 520 // append name
509 { 521 {
(...skipping 10 matching lines...) Expand all
520 // insert source 532 // insert source
521 _insertBuilder(sb); 533 _insertBuilder(sb);
522 if (targetFile == file) { 534 if (targetFile == file) {
523 _addLinkedPosition("NAME", rf.rangeNode(name)); 535 _addLinkedPosition("NAME", rf.rangeNode(name));
524 } 536 }
525 // add proposal 537 // add proposal
526 _addFix(FixKind.CREATE_CONSTRUCTOR, [constructorName], fixFile: targetFile); 538 _addFix(FixKind.CREATE_CONSTRUCTOR, [constructorName], fixFile: targetFile);
527 } 539 }
528 540
529 void _addFix_createFunction_forFunctionType() { 541 void _addFix_createFunction_forFunctionType() {
530 // TODO(scheglov) implement 542 if (node is SimpleIdentifier) {
531 // if (node is SimpleIdentifier) { 543 SimpleIdentifier nameNode = node as SimpleIdentifier;
532 // SimpleIdentifier nameNode = node as SimpleIdentifier; 544 // prepare argument expression (to get parameter)
533 // // prepare argument expression (to get parameter) 545 ClassElement targetElement;
534 // ClassElement targetElement; 546 Expression argument;
535 // Expression argument; 547 {
536 // { 548 Expression target = getQualifiedPropertyTarget(node);
537 // Expression target = CorrectionUtils.getQualifiedPropertyTarget(node); 549 if (target != null) {
538 // if (target != null) { 550 DartType targetType = target.bestType;
539 // DartType targetType = target.bestType; 551 if (targetType != null && targetType.element is ClassElement) {
540 // if (targetType != null && targetType.element is ClassElement) { 552 targetElement = targetType.element as ClassElement;
541 // targetElement = targetType.element as ClassElement; 553 argument = target.parent as Expression;
542 // argument = target.parent as Expression; 554 } else {
543 // } else { 555 return;
544 // return; 556 }
545 // } 557 } else {
546 // } else { 558 ClassDeclaration enclosingClass =
547 // ClassDeclaration enclosingClass = 559 node.getAncestor((node) => node is ClassDeclaration);
548 // node.getAncestor((node) => node is ClassDeclaration); 560 targetElement = enclosingClass != null ?
549 // targetElement = enclosingClass != null ? 561 enclosingClass.element :
550 // enclosingClass.element : 562 null;
551 // null; 563 argument = nameNode;
552 // argument = nameNode; 564 }
553 // } 565 }
554 // } 566 // should be argument of some invocation
555 // // should be argument of some invocation 567 ParameterElement parameterElement = argument.bestParameterElement;
556 // ParameterElement parameterElement = argument.bestParameterElement; 568 if (parameterElement == null) {
557 // if (parameterElement == null) { 569 return;
558 // return; 570 }
559 // } 571 // should be parameter of function type
560 // // should be parameter of function type 572 DartType parameterType = parameterElement.type;
561 // DartType parameterType = parameterElement.type; 573 if (parameterType is! FunctionType) {
562 // if (parameterType is! FunctionType) { 574 return;
563 // return; 575 }
564 // } 576 FunctionType functionType = parameterType as FunctionType;
565 // FunctionType functionType = parameterType as FunctionType; 577 // add proposal
566 // // add proposal 578 if (targetElement != null) {
567 // if (targetElement != null) { 579 _addProposal_createFunction_method(targetElement, functionType);
568 // _addProposal_createFunction_method(targetElement, functionType); 580 } else {
569 // } else { 581 _addProposal_createFunction_function(functionType);
570 // _addProposal_createFunction_function(functionType); 582 }
571 // } 583 }
572 // }
573 } 584 }
574 585
575 void 586 void
576 _addFix_createMissingOverrides(List<ExecutableElement> missingOverrides) { 587 _addFix_createMissingOverrides(List<ExecutableElement> missingOverrides) {
577 // TODO(scheglov) implement 588 // sort by name
578 // // sort by name 589 missingOverrides.sort((Element firstElement, Element secondElement) {
579 // missingOverrides.sort( 590 return compareStrings(
580 // (Element firstElement, Element secondElement) => 591 firstElement.displayName,
581 // ObjectUtils.compare(firstElement.displayName, secondElement.displa yName)); 592 secondElement.displayName);
582 // // add elements 593 });
583 // ClassDeclaration targetClass = node.parent as ClassDeclaration; 594 // TODO
584 // bool isFirst = true; 595 ClassDeclaration targetClass = node.parent as ClassDeclaration;
585 // for (ExecutableElement missingOverride in missingOverrides) { 596 int insertOffset = targetClass.end - 1;
586 // _addFix_createMissingOverrides_single( 597 SourceBuilder sb = new SourceBuilder(file, insertOffset);
587 // targetClass, 598 // add elements
588 // missingOverride, 599 bool isFirst = true;
589 // isFirst); 600 for (ExecutableElement missingOverride in missingOverrides) {
590 // isFirst = false; 601 if (!isFirst || !targetClass.members.isEmpty) {
591 // } 602 sb.append(eol);
592 // // add proposal 603 }
593 // _addFix( 604 _addFix_createMissingOverrides_single(sb, targetClass, missingOverride);
594 // FixKind.CREATE_MISSING_OVERRIDES, 605 isFirst = false;
595 // [missingOverrides.length]); 606 }
607 // add proposal
608 endPosition = new Position(file, insertOffset, 0);
609 _insertBuilder(sb);
610 _addFix(FixKind.CREATE_MISSING_OVERRIDES, [missingOverrides.length]);
596 } 611 }
597 612
598 void _addFix_createMissingOverrides_single(ClassDeclaration targetClass, 613 void _addFix_createMissingOverrides_single(SourceBuilder sb,
599 ExecutableElement missingOverride, bool isFirst) { 614 ClassDeclaration targetClass, ExecutableElement missingOverride) {
600 // TODO(scheglov) implement 615 // prepare environment
601 // // prepare environment 616 String prefix = utils.getIndent(1);
602 // String eol = utils.endOfLine; 617 String prefix2 = utils.getIndent(2);
603 // String prefix = utils.getIndent(1); 618 // may be property
604 // String prefix2 = utils.getIndent(2); 619 ElementKind elementKind = missingOverride.kind;
605 // int insertOffset = targetClass.end - 1; 620 bool isGetter = elementKind == ElementKind.GETTER;
606 // // prepare source 621 bool isSetter = elementKind == ElementKind.SETTER;
607 // JavaStringBuilder sb = new JavaStringBuilder(); 622 bool isMethod = elementKind == ElementKind.METHOD;
608 // // may be empty line 623 bool isOperator = isMethod && (missingOverride as MethodElement).isOperator;
609 // if (!isFirst || !targetClass.members.isEmpty) { 624 sb.append(prefix);
610 // sb.append(eol); 625 if (isGetter) {
611 // } 626 sb.append('// TODO: implement ${missingOverride.displayName}');
612 // // may be property 627 sb.append(eol);
613 // ElementKind elementKind = missingOverride.kind; 628 sb.append(prefix);
614 // bool isGetter = elementKind == ElementKind.GETTER; 629 }
615 // bool isSetter = elementKind == ElementKind.SETTER; 630 // @override
616 // bool isMethod = elementKind == ElementKind.METHOD; 631 {
617 // bool isOperator = isMethod && (missingOverride as MethodElement).isOperato r; 632 sb.append('@override');
618 // sb.append(prefix); 633 sb.append(eol);
619 // if (isGetter) { 634 sb.append(prefix);
620 // sb.append("// TODO: implement ${missingOverride.displayName}"); 635 }
621 // sb.append(eol); 636 // return type
622 // sb.append(prefix); 637 _appendType(sb, missingOverride.type.returnType);
623 // } 638 if (isGetter) {
624 // // @override 639 sb.append('get ');
625 // { 640 } else if (isSetter) {
626 // sb.append("@override"); 641 sb.append('set ');
627 // sb.append(eol); 642 } else if (isOperator) {
628 // sb.append(prefix); 643 sb.append('operator ');
629 // } 644 }
630 // // return type 645 // name
631 // _appendType(sb, missingOverride.type.returnType); 646 sb.append(missingOverride.displayName);
632 // if (isGetter) { 647 // parameters + body
633 // sb.append("get "); 648 if (isGetter) {
634 // } else if (isSetter) { 649 sb.append(' => null;');
635 // sb.append("set "); 650 } else {
636 // } else if (isOperator) { 651 List<ParameterElement> parameters = missingOverride.parameters;
637 // sb.append("operator "); 652 _appendParameters(sb, parameters, _getDefaultValueMap(parameters));
638 // } 653 sb.append(' {');
639 // // name 654 // TO-DO
640 // sb.append(missingOverride.displayName); 655 sb.append(eol);
641 // // parameters + body 656 sb.append(prefix2);
642 // if (isGetter) { 657 sb.append('// TODO: implement ${missingOverride.displayName}');
643 // sb.append(" => null;"); 658 sb.append(eol);
644 // } else if (isMethod || isSetter) { 659 // close method
645 // List<ParameterElement> parameters = missingOverride.parameters; 660 sb.append(prefix);
646 // _appendParameters(sb, parameters); 661 sb.append('}');
647 // sb.append(" {"); 662 }
648 // // TO-DO 663 sb.append(eol);
649 // sb.append(eol);
650 // sb.append(prefix2);
651 // if (isMethod) {
652 // sb.append("// TODO: implement ${missingOverride.displayName}");
653 // } else {
654 // sb.append("// TODO: implement ${missingOverride.displayName}");
655 // }
656 // sb.append(eol);
657 // // close method
658 // sb.append(prefix);
659 // sb.append("}");
660 // }
661 // sb.append(eol);
662 // // done
663 // _addInsertEdit(insertOffset, sb.toString());
664 // // maybe set end range
665 // if (_endRange == null) {
666 // _endRange = SourceRangeFactory.rangeStartLength(insertOffset, 0);
667 // }
668 } 664 }
669 665
670 void _addFix_createNoSuchMethod() { 666 void _addFix_createNoSuchMethod() {
671 // TODO(scheglov) implement 667 ClassDeclaration targetClass = node.parent as ClassDeclaration;
672 // ClassDeclaration targetClass = node.parent as ClassDeclaration; 668 // prepare environment
673 // // prepare environment 669 String prefix = utils.getIndent(1);
674 // String eol = utils.endOfLine; 670 int insertOffset = targetClass.end - 1;
675 // String prefix = utils.getIndent(1); 671 // prepare source
676 // int insertOffset = targetClass.end - 1; 672 SourceBuilder sb = new SourceBuilder(file, insertOffset);
677 // // prepare source 673 {
678 // SourceBuilder sb = new SourceBuilder.con1(insertOffset); 674 // insert empty line before existing member
679 // { 675 if (!targetClass.members.isEmpty) {
680 // // insert empty line before existing member 676 sb.append(eol);
681 // if (!targetClass.members.isEmpty) { 677 }
682 // sb.append(eol); 678 // append method
683 // } 679 sb.append(prefix);
684 // // append method 680 sb.append(
685 // sb.append(prefix); 681 "noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation) ;");
686 // sb.append( 682 sb.append(eol);
687 // "noSuchMethod(Invocation invocation) => super.noSuchMethod(invocatio n);"); 683 }
688 // sb.append(eol); 684 // done
689 // } 685 _insertBuilder(sb);
690 // // done 686 endPosition = new Position(file, insertOffset, 0);
691 // _addInsertEdit3(sb); 687 // add proposal
692 // _endRange = SourceRangeFactory.rangeStartLength(insertOffset, 0); 688 _addFix(FixKind.CREATE_NO_SUCH_METHOD, []);
693 // // add proposal
694 // _addFix(FixKind.CREATE_NO_SUCH_METHOD, []);
695 } 689 }
696 690
691
697 void _addFix_createPart() { 692 void _addFix_createPart() {
698 // TODO(scheglov) implement 693 // TODO(scheglov) implement
699 // if (node is SimpleStringLiteral && node.parent is PartDirective) { 694 // if (node is SimpleStringLiteral && node.parent is PartDirective) {
700 // SimpleStringLiteral uriLiteral = node as SimpleStringLiteral; 695 // SimpleStringLiteral uriLiteral = node as SimpleStringLiteral;
701 // String uriString = uriLiteral.value; 696 // String uriString = uriLiteral.value;
702 // // prepare referenced File 697 // // prepare referenced File
703 // JavaFile newFile; 698 // JavaFile newFile;
704 // { 699 // {
705 // Uri uri = parseUriWithException(uriString); 700 // Uri uri = parseUriWithException(uriString);
706 // if (uri.isAbsolute) { 701 // if (uri.isAbsolute) {
707 // return; 702 // return;
708 // } 703 // }
709 // newFile = new JavaFile.relative(_unitLibraryFolder, uriString); 704 // newFile = new JavaFile.relative(_unitLibraryFolder, uriString);
710 // } 705 // }
711 // if (!newFile.exists()) { 706 // if (!newFile.exists()) {
712 // // prepare new source 707 // // prepare new source
713 // String source; 708 // String source;
714 // { 709 // {
715 // String eol = utils.endOfLine;
716 // String libraryName = _unitLibraryElement.displayName; 710 // String libraryName = _unitLibraryElement.displayName;
717 // source = "part of ${libraryName};${eol}${eol}"; 711 // source = "part of ${libraryName};${eol}${eol}";
718 // } 712 // }
719 // // add proposal 713 // // add proposal
720 // _proposals.add( 714 // _proposals.add(
721 // new CreateFileCorrectionProposal( 715 // new CreateFileCorrectionProposal(
722 // newFile, 716 // newFile,
723 // source, 717 // source,
724 // FixKind.CREATE_PART, 718 // FixKind.CREATE_PART,
725 // [uriString])); 719 // [uriString]));
726 // } 720 // }
727 // } 721 // }
728 } 722 }
729 723
730 void _addFix_importLibrary(FixKind kind, String importPath) { 724 void _addFix_importLibrary(FixKind kind, String importPath) {
731 // TODO(scheglov) implement 725 // TODO(scheglov) implement
732 // CompilationUnitElement libraryUnitElement = 726 // CompilationUnitElement libraryUnitElement =
733 // _unitLibraryElement.definingCompilationUnit; 727 // _unitLibraryElement.definingCompilationUnit;
734 // CompilationUnit libraryUnit = libraryUnitElement.node; 728 // CompilationUnit libraryUnit = libraryUnitElement.node;
735 // // prepare new import location 729 // // prepare new import location
736 // int offset = 0; 730 // int offset = 0;
737 // String prefix; 731 // String prefix;
738 // String suffix; 732 // String suffix;
739 // { 733 // {
740 // String eol = utils.endOfLine;
741 // // if no directives 734 // // if no directives
742 // prefix = ""; 735 // prefix = "";
743 // suffix = eol; 736 // suffix = eol;
744 // CorrectionUtils libraryUtils = new CorrectionUtils(libraryUnit); 737 // CorrectionUtils libraryUtils = new CorrectionUtils(libraryUnit);
745 // // after last directive in library 738 // // after last directive in library
746 // for (Directive directive in libraryUnit.directives) { 739 // for (Directive directive in libraryUnit.directives) {
747 // if (directive is LibraryDirective || directive is ImportDirective) { 740 // if (directive is LibraryDirective || directive is ImportDirective) {
748 // offset = directive.end; 741 // offset = directive.end;
749 // prefix = eol; 742 // prefix = eol;
750 // suffix = ""; 743 // suffix = "";
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 // return; 1063 // return;
1071 // } 1064 // }
1072 // String name = (node as SimpleIdentifier).name; 1065 // String name = (node as SimpleIdentifier).name;
1073 // MethodInvocation invocation = node.parent as MethodInvocation; 1066 // MethodInvocation invocation = node.parent as MethodInvocation;
1074 // // function invocation has no target 1067 // // function invocation has no target
1075 // Expression target = invocation.realTarget; 1068 // Expression target = invocation.realTarget;
1076 // if (target != null) { 1069 // if (target != null) {
1077 // return; 1070 // return;
1078 // } 1071 // }
1079 // // prepare environment 1072 // // prepare environment
1080 // String eol = utils.endOfLine;
1081 // int insertOffset; 1073 // int insertOffset;
1082 // String sourcePrefix; 1074 // String sourcePrefix;
1083 // AstNode enclosingMember = 1075 // AstNode enclosingMember =
1084 // node.getAncestor((node) => node is CompilationUnitMember); 1076 // node.getAncestor((node) => node is CompilationUnitMember);
1085 // insertOffset = enclosingMember.end; 1077 // insertOffset = enclosingMember.end;
1086 // sourcePrefix = "${eol}${eol}"; 1078 // sourcePrefix = "${eol}${eol}";
1087 // // build method source 1079 // // build method source
1088 // SourceBuilder sb = new SourceBuilder.con1(insertOffset); 1080 // SourceBuilder sb = new SourceBuilder.con1(insertOffset);
1089 // { 1081 // {
1090 // sb.append(sourcePrefix); 1082 // sb.append(sourcePrefix);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 // String closestName = null; 1136 // String closestName = null;
1145 // if (finder != null && finder._distance < 5) { 1137 // if (finder != null && finder._distance < 5) {
1146 // closestName = finder._element.name; 1138 // closestName = finder._element.name;
1147 // _addReplaceEdit(SourceRangeFactory.rangeNode(node), closestName); 1139 // _addReplaceEdit(SourceRangeFactory.rangeNode(node), closestName);
1148 // _addFix(FixKind.CHANGE_TO, [closestName]); 1140 // _addFix(FixKind.CHANGE_TO, [closestName]);
1149 // } 1141 // }
1150 // } 1142 // }
1151 } 1143 }
1152 1144
1153 void _addFix_undefinedMethod_create() { 1145 void _addFix_undefinedMethod_create() {
1154 // TODO(scheglov) implement 1146 if (node is SimpleIdentifier && node.parent is MethodInvocation) {
1155 // if (node is SimpleIdentifier && node.parent is MethodInvocation) { 1147 String name = (node as SimpleIdentifier).name;
1156 // String name = (node as SimpleIdentifier).name; 1148 MethodInvocation invocation = node.parent as MethodInvocation;
1157 // MethodInvocation invocation = node.parent as MethodInvocation; 1149 // prepare environment
1158 // // prepare environment 1150 Source targetSource;
1159 // String eol = utils.endOfLine; 1151 String prefix;
1160 // Source targetSource; 1152 int insertOffset;
1161 // String prefix; 1153 String sourcePrefix;
1162 // int insertOffset; 1154 String sourceSuffix;
1163 // String sourcePrefix; 1155 bool staticModifier = false;
1164 // String sourceSuffix; 1156 Expression target = invocation.realTarget;
1165 // bool staticModifier = false; 1157 if (target == null) {
1166 // Expression target = invocation.realTarget; 1158 targetSource = source;
1167 // if (target == null) { 1159 ClassMember enclosingMember =
1168 // targetSource = _source; 1160 node.getAncestor((node) => node is ClassMember);
1169 // ClassMember enclosingMember = 1161 staticModifier = _inStaticContext();
1170 // node.getAncestor((node) => node is ClassMember); 1162 prefix = utils.getNodePrefix(enclosingMember);
1171 // staticModifier = _inStaticMemberContext2(enclosingMember); 1163 insertOffset = enclosingMember.end;
1172 // prefix = utils.getNodePrefix(enclosingMember); 1164 sourcePrefix = "${eol}${prefix}${eol}";
1173 // insertOffset = enclosingMember.end; 1165 sourceSuffix = "";
1174 // sourcePrefix = "${eol}${prefix}${eol}"; 1166 } else {
1175 // sourceSuffix = ""; 1167 // prepare target interface type
1176 // } else { 1168 DartType targetType = target.bestType;
1177 // // prepare target interface type 1169 if (targetType is! InterfaceType) {
1178 // DartType targetType = target.bestType; 1170 return;
1179 // if (targetType is! InterfaceType) { 1171 }
1180 // return; 1172 ClassElement targetElement = targetType.element as ClassElement;
1181 // } 1173 targetSource = targetElement.source;
1182 // ClassElement targetElement = targetType.element as ClassElement; 1174 // may be static
1183 // targetSource = targetElement.source; 1175 if (target is Identifier) {
1184 // // may be static 1176 staticModifier = target.bestElement.kind == ElementKind.CLASS;
1185 // if (target is Identifier) { 1177 }
1186 // staticModifier = target.bestElement.kind == ElementKind.CLASS; 1178 // prepare insert offset
1187 // } 1179 ClassDeclaration targetClass = targetElement.node;
1188 // // prepare insert offset 1180 prefix = " ";
1189 // ClassDeclaration targetClass = targetElement.node; 1181 insertOffset = targetClass.end - 1;
1190 // prefix = " "; 1182 if (targetClass.members.isEmpty) {
1191 // insertOffset = targetClass.end - 1; 1183 sourcePrefix = "";
1192 // if (targetClass.members.isEmpty) { 1184 } else {
1193 // sourcePrefix = ""; 1185 sourcePrefix = eol;
1194 // } else { 1186 }
1195 // sourcePrefix = "${prefix}${eol}"; 1187 sourceSuffix = eol;
1196 // } 1188 }
1197 // sourceSuffix = eol; 1189 String targetFile = targetSource.fullName;
1198 // } 1190 // build method source
1199 // // build method source 1191 SourceBuilder sb = new SourceBuilder(targetFile, insertOffset);
1200 // SourceBuilder sb = new SourceBuilder.con1(insertOffset); 1192 {
1201 // { 1193 sb.append(sourcePrefix);
1202 // sb.append(sourcePrefix); 1194 sb.append(prefix);
1203 // sb.append(prefix); 1195 // maybe "static"
1204 // // may be "static" 1196 if (staticModifier) {
1205 // if (staticModifier) { 1197 sb.append("static ");
1206 // sb.append("static "); 1198 }
1207 // } 1199 // append return type
1208 // // may be return type 1200 _appendType(sb, _inferReturnType(invocation), 'RETURN_TYPE');
1209 // { 1201 // append name
1210 // DartType type = 1202 {
1211 // _addFix_undefinedMethod_create_getReturnType(invocation); 1203 sb.startPosition("NAME");
1212 // if (type != null) { 1204 sb.append(name);
1213 // String typeSource = utils.getTypeSource2(type); 1205 sb.endPosition();
1214 // if (typeSource != "dynamic") { 1206 }
1215 // sb.startPosition("RETURN_TYPE"); 1207 _addFix_undefinedMethod_create_parameters(sb, invocation.argumentList);
1216 // sb.append(typeSource); 1208 sb.append(") {${eol}${prefix}}");
1217 // sb.endPosition(); 1209 sb.append(sourceSuffix);
1218 // sb.append(" "); 1210 }
1219 // } 1211 // insert source
1220 // } 1212 _insertBuilder(sb);
1221 // } 1213 // add linked positions
1222 // // append name 1214 if (targetSource == source) {
1223 // { 1215 _addLinkedPosition3('NAME', sb, rf.rangeNode(node));
1224 // sb.startPosition("NAME"); 1216 }
1225 // sb.append(name); 1217 // add proposal
1226 // sb.endPosition(); 1218 _addFix(FixKind.CREATE_METHOD, [name], fixFile: targetFile);
1227 // } 1219 }
1228 // _addFix_undefinedMethod_create_parameters(sb, invocation.argumentList) ;
1229 // sb.append(") {${eol}${prefix}}");
1230 // sb.append(sourceSuffix);
1231 // }
1232 // // insert source
1233 // _addInsertEdit(insertOffset, sb.toString());
1234 // // add linked positions
1235 // if (targetSource == _source) {
1236 // _addLinkedPosition("NAME", sb, SourceRangeFactory.rangeNode(node));
1237 // }
1238 // _addLinkedPositions(sb);
1239 // // add proposal
1240 // _addUnitCorrectionProposal2(
1241 // targetSource,
1242 // FixKind.CREATE_METHOD,
1243 // [name]);
1244 // }
1245 }
1246
1247 /**
1248 * @return the possible return [Type], may be <code>null</code> if can not be identified.
1249 */
1250 DartType
1251 _addFix_undefinedMethod_create_getReturnType(MethodInvocation invocation) {
1252 // TODO(scheglov) implement
1253 // AstNode parent = invocation.parent;
1254 // // myFunction();
1255 // if (parent is ExpressionStatement) {
1256 // return VoidTypeImpl.instance;
1257 // }
1258 // // return myFunction();
1259 // if (parent is ReturnStatement) {
1260 // ExecutableElement executable =
1261 // CorrectionUtils.getEnclosingExecutableElement(invocation);
1262 // return executable != null ? executable.returnType : null;
1263 // }
1264 // // int v = myFunction();
1265 // if (parent is VariableDeclaration) {
1266 // VariableDeclaration variableDeclaration = parent;
1267 // if (identical(variableDeclaration.initializer, invocation)) {
1268 // VariableElement variableElement = variableDeclaration.element;
1269 // if (variableElement != null) {
1270 // return variableElement.type;
1271 // }
1272 // }
1273 // }
1274 // // v = myFunction();
1275 // if (parent is AssignmentExpression) {
1276 // AssignmentExpression assignment = parent;
1277 // if (identical(assignment.rightHandSide, invocation)) {
1278 // if (assignment.operator.type == TokenType.EQ) {
1279 // // v = myFunction();
1280 // Expression lhs = assignment.leftHandSide;
1281 // if (lhs != null) {
1282 // return lhs.bestType;
1283 // }
1284 // } else {
1285 // // v += myFunction();
1286 // MethodElement method = assignment.bestElement;
1287 // if (method != null) {
1288 // List<ParameterElement> parameters = method.parameters;
1289 // if (parameters.length == 1) {
1290 // return parameters[0].type;
1291 // }
1292 // }
1293 // }
1294 // }
1295 // }
1296 // // v + myFunction();
1297 // if (parent is BinaryExpression) {
1298 // BinaryExpression binary = parent;
1299 // MethodElement method = binary.bestElement;
1300 // if (method != null) {
1301 // if (identical(binary.rightOperand, invocation)) {
1302 // List<ParameterElement> parameters = method.parameters;
1303 // return parameters.length == 1 ? parameters[0].type : null;
1304 // }
1305 // }
1306 // }
1307 // // foo( myFunction() );
1308 // if (parent is ArgumentList) {
1309 // ParameterElement parameter = invocation.bestParameterElement;
1310 // return parameter != null ? parameter.type : null;
1311 // }
1312 // // bool
1313 // {
1314 // // assert( myFunction() );
1315 // if (parent is AssertStatement) {
1316 // AssertStatement statement = parent;
1317 // if (identical(statement.condition, invocation)) {
1318 // return coreTypeBool;
1319 // }
1320 // }
1321 // // if ( myFunction() ) {}
1322 // if (parent is IfStatement) {
1323 // IfStatement statement = parent;
1324 // if (identical(statement.condition, invocation)) {
1325 // return coreTypeBool;
1326 // }
1327 // }
1328 // // while ( myFunction() ) {}
1329 // if (parent is WhileStatement) {
1330 // WhileStatement statement = parent;
1331 // if (identical(statement.condition, invocation)) {
1332 // return coreTypeBool;
1333 // }
1334 // }
1335 // // do {} while ( myFunction() );
1336 // if (parent is DoStatement) {
1337 // DoStatement statement = parent;
1338 // if (identical(statement.condition, invocation)) {
1339 // return coreTypeBool;
1340 // }
1341 // }
1342 // // !myFunction()
1343 // if (parent is PrefixExpression) {
1344 // PrefixExpression prefixExpression = parent;
1345 // if (prefixExpression.operator.type == TokenType.BANG) {
1346 // return coreTypeBool;
1347 // }
1348 // }
1349 // // binary expression '&&' or '||'
1350 // if (parent is BinaryExpression) {
1351 // BinaryExpression binaryExpression = parent;
1352 // TokenType operatorType = binaryExpression.operator.type;
1353 // if (operatorType == TokenType.AMPERSAND_AMPERSAND ||
1354 // operatorType == TokenType.BAR_BAR) {
1355 // return coreTypeBool;
1356 // }
1357 // }
1358 // }
1359 // we don't know
1360 return null;
1361 } 1220 }
1362 1221
1363 void _addFix_undefinedMethod_create_parameters(SourceBuilder sb, 1222 void _addFix_undefinedMethod_create_parameters(SourceBuilder sb,
1364 ArgumentList argumentList) { 1223 ArgumentList argumentList) {
1365 // append parameters 1224 // append parameters
1366 sb.append("("); 1225 sb.append("(");
1367 Set<String> excluded = new Set(); 1226 Set<String> excluded = new Set();
1368 List<Expression> arguments = argumentList.arguments; 1227 List<Expression> arguments = argumentList.arguments;
1369 for (int i = 0; i < arguments.length; i++) { 1228 for (int i = 0; i < arguments.length; i++) {
1370 Expression argument = arguments[i]; 1229 Expression argument = arguments[i];
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 void _addLinkedPosition2(String groupId, Position position) { 1369 void _addLinkedPosition2(String groupId, Position position) {
1511 LinkedPositionGroup group = linkedPositionGroups[groupId]; 1370 LinkedPositionGroup group = linkedPositionGroups[groupId];
1512 if (group == null) { 1371 if (group == null) {
1513 group = new LinkedPositionGroup(groupId); 1372 group = new LinkedPositionGroup(groupId);
1514 linkedPositionGroups[groupId] = group; 1373 linkedPositionGroups[groupId] = group;
1515 } 1374 }
1516 group.add(position); 1375 group.add(position);
1517 } 1376 }
1518 1377
1519 /** 1378 /**
1379 * Adds a single linked position to [groupId].
1380 */
1381 void _addLinkedPosition3(String groupId, SourceBuilder sb,
1382 SourceRange range) {
1383 if (sb.offset < range.offset) {
1384 int delta = sb.length;
1385 range = range.getTranslated(delta);
1386 }
1387 _addLinkedPosition(groupId, range);
1388 }
1389
1390 /**
1391 * Prepares proposal for creating function corresponding to the given [Functio nType].
1392 */
1393 void _addProposal_createFunction(FunctionType functionType, String name,
1394 Source targetSource, int insertOffset, bool isStatic, String prefix,
1395 String sourcePrefix, String sourceSuffix) {
1396 // build method source
1397 String targetFile = targetSource.fullName;
1398 SourceBuilder sb = new SourceBuilder(targetFile, insertOffset);
1399 {
1400 sb.append(sourcePrefix);
1401 sb.append(prefix);
1402 // may be static
1403 if (isStatic) {
1404 sb.append("static ");
1405 }
1406 // append return type
1407 _appendType(sb, functionType.returnType, 'RETURN_TYPE');
1408 // append name
1409 {
1410 sb.startPosition("NAME");
1411 sb.append(name);
1412 sb.endPosition();
1413 }
1414 // append parameters
1415 sb.append("(");
1416 List<ParameterElement> parameters = functionType.parameters;
1417 for (int i = 0; i < parameters.length; i++) {
1418 ParameterElement parameter = parameters[i];
1419 // append separator
1420 if (i != 0) {
1421 sb.append(", ");
1422 }
1423 // append type name
1424 DartType type = parameter.type;
1425 if (!type.isDynamic) {
1426 String typeSource = utils.getTypeSource(type);
1427 {
1428 sb.startPosition("TYPE${i}");
1429 sb.append(typeSource);
1430 _addSuperTypeProposals(sb, new Set(), type);
1431 sb.endPosition();
1432 }
1433 sb.append(" ");
1434 }
1435 // append parameter name
1436 {
1437 sb.startPosition("ARG${i}");
1438 sb.append(parameter.displayName);
1439 sb.endPosition();
1440 }
1441 }
1442 sb.append(")");
1443 // close method
1444 sb.append(" {${eol}${prefix}}");
1445 sb.append(sourceSuffix);
1446 }
1447 // insert source
1448 _insertBuilder(sb);
1449 // add linked positions
1450 if (targetSource == source) {
1451 _addLinkedPosition3("NAME", sb, rf.rangeNode(node));
1452 }
1453 }
1454
1455 /**
1456 * Adds proposal for creating method corresponding to the given [FunctionType] in the given
1457 * [ClassElement].
1458 */
1459 void _addProposal_createFunction_function(FunctionType functionType) {
1460 String name = (node as SimpleIdentifier).name;
1461 // prepare environment
1462 int insertOffset = unit.end;
1463 // prepare prefix
1464 String prefix = "";
1465 String sourcePrefix = "${eol}";
1466 String sourceSuffix = eol;
1467 _addProposal_createFunction(
1468 functionType,
1469 name,
1470 source,
1471 insertOffset,
1472 false,
1473 prefix,
1474 sourcePrefix,
1475 sourceSuffix);
1476 // add proposal
1477 _addFix(FixKind.CREATE_FUNCTION, [name], fixFile: file);
1478 }
1479
1480 /**
1481 * Adds proposal for creating method corresponding to the given [FunctionType] in the given
1482 * [ClassElement].
1483 */
1484 void _addProposal_createFunction_method(ClassElement targetClassElement,
1485 FunctionType functionType) {
1486 String name = (node as SimpleIdentifier).name;
1487 // prepare environment
1488 Source targetSource = targetClassElement.source;
1489 String targetFile = targetSource.fullName;
1490 // prepare insert offset
1491 ClassDeclaration targetClassNode = targetClassElement.node;
1492 int insertOffset = targetClassNode.end - 1;
1493 // prepare prefix
1494 String prefix = " ";
1495 String sourcePrefix;
1496 if (targetClassNode.members.isEmpty) {
1497 sourcePrefix = "";
1498 } else {
1499 sourcePrefix = eol;
1500 }
1501 String sourceSuffix = eol;
1502 _addProposal_createFunction(
1503 functionType,
1504 name,
1505 targetSource,
1506 insertOffset,
1507 _inStaticContext(),
1508 prefix,
1509 sourcePrefix,
1510 sourceSuffix);
1511 // add proposal
1512 _addFix(FixKind.CREATE_METHOD, [name], fixFile: targetFile);
1513 }
1514
1515 /**
1520 * Adds a new [Edit] to [edits]. 1516 * Adds a new [Edit] to [edits].
1521 */ 1517 */
1522 void _addRemoveEdit(SourceRange range) { 1518 void _addRemoveEdit(SourceRange range) {
1523 _addReplaceEdit(range, ''); 1519 _addReplaceEdit(range, '');
1524 } 1520 }
1525 1521
1526 /** 1522 /**
1527 * Adds a new [Edit] to [edits]. 1523 * Adds a new [Edit] to [edits].
1528 */ 1524 */
1529 void _addReplaceEdit(SourceRange range, String text) { 1525 void _addReplaceEdit(SourceRange range, String text) {
1530 Edit edit = new Edit(range.offset, range.length, text); 1526 Edit edit = new Edit(range.offset, range.length, text);
1531 edits.add(edit); 1527 edits.add(edit);
1532 } 1528 }
1533 1529
1534 void _appendParameterSource(StringBuffer sb, DartType type, String name) { 1530 void _appendParameterSource(SourceBuilder sb, DartType type, String name) {
1535 String parameterSource = utils.getParameterSource(type, name); 1531 String parameterSource = utils.getParameterSource(type, name);
1536 sb.write(parameterSource); 1532 sb.append(parameterSource);
1537 } 1533 }
1538 1534
1539 void _appendParameters(StringBuffer sb, List<ParameterElement> parameters, 1535 void _appendParameters(SourceBuilder sb, List<ParameterElement> parameters,
1540 Map<ParameterElement, String> defaultValueMap) { 1536 Map<ParameterElement, String> defaultValueMap) {
1541 sb.write("("); 1537 sb.append("(");
1542 bool firstParameter = true; 1538 bool firstParameter = true;
1543 bool sawNamed = false; 1539 bool sawNamed = false;
1544 bool sawPositional = false; 1540 bool sawPositional = false;
1545 for (ParameterElement parameter in parameters) { 1541 for (ParameterElement parameter in parameters) {
1546 if (!firstParameter) { 1542 if (!firstParameter) {
1547 sb.write(", "); 1543 sb.append(", ");
1548 } else { 1544 } else {
1549 firstParameter = false; 1545 firstParameter = false;
1550 } 1546 }
1551 // may be optional 1547 // may be optional
1552 ParameterKind parameterKind = parameter.parameterKind; 1548 ParameterKind parameterKind = parameter.parameterKind;
1553 if (parameterKind == ParameterKind.NAMED) { 1549 if (parameterKind == ParameterKind.NAMED) {
1554 if (!sawNamed) { 1550 if (!sawNamed) {
1555 sb.write("{"); 1551 sb.append("{");
1556 sawNamed = true; 1552 sawNamed = true;
1557 } 1553 }
1558 } 1554 }
1559 if (parameterKind == ParameterKind.POSITIONAL) { 1555 if (parameterKind == ParameterKind.POSITIONAL) {
1560 if (!sawPositional) { 1556 if (!sawPositional) {
1561 sb.write("["); 1557 sb.append("[");
1562 sawPositional = true; 1558 sawPositional = true;
1563 } 1559 }
1564 } 1560 }
1565 // parameter 1561 // parameter
1566 _appendParameterSource(sb, parameter.type, parameter.name); 1562 _appendParameterSource(sb, parameter.type, parameter.name);
1567 // default value 1563 // default value
1568 if (defaultValueMap != null) { 1564 if (defaultValueMap != null) {
1569 String defaultSource = defaultValueMap[parameter]; 1565 String defaultSource = defaultValueMap[parameter];
1570 if (defaultSource != null) { 1566 if (defaultSource != null) {
1571 if (sawPositional) { 1567 if (sawPositional) {
1572 sb.write(" = "); 1568 sb.append(" = ");
1573 } else { 1569 } else {
1574 sb.write(": "); 1570 sb.append(": ");
1575 } 1571 }
1576 sb.write(defaultSource); 1572 sb.append(defaultSource);
1577 } 1573 }
1578 } 1574 }
1579 } 1575 }
1580 // close parameters 1576 // close parameters
1581 if (sawNamed) { 1577 if (sawNamed) {
1582 sb.write("}"); 1578 sb.append("}");
1583 } 1579 }
1584 if (sawPositional) { 1580 if (sawPositional) {
1585 sb.write("]"); 1581 sb.append("]");
1586 } 1582 }
1587 sb.write(")"); 1583 sb.append(")");
1588 } 1584 }
1589 1585
1590 // void _addLinkedPositionProposal(String group, 1586 void _appendType(SourceBuilder sb, DartType type, [String groupId]) {
1591 // LinkedPositionProposal proposal) { 1587 if (type != null && !type.isDynamic) {
1592 // List<LinkedPositionProposal> nodeProposals = linkedPositionProposals[group ]; 1588 String typeSource = utils.getTypeSource(type);
1593 // if (nodeProposals == null) { 1589 if (groupId != null) {
1594 // nodeProposals = <LinkedPositionProposal>[]; 1590 sb.startPosition(groupId);
1595 // linkedPositionProposals[group] = nodeProposals; 1591 sb.append(typeSource);
1596 // } 1592 sb.endPosition();
1597 // nodeProposals.add(proposal); 1593 } else {
1598 // } 1594 sb.append(typeSource);
1595 }
1596 sb.append(' ');
1597 }
1598 }
1599 1599
1600 /** 1600 /**
1601 * @return the string to display as the name of the given constructor in a pro posal name. 1601 * @return the string to display as the name of the given constructor in a pro posal name.
1602 */ 1602 */
1603 String _getConstructorProposalName(ConstructorElement constructor) { 1603 String _getConstructorProposalName(ConstructorElement constructor) {
1604 StringBuffer proposalNameBuffer = new StringBuffer(); 1604 SourceBuilder proposalNameBuffer = new SourceBuilder.buffer();
1605 proposalNameBuffer.write("super"); 1605 proposalNameBuffer.append("super");
1606 // may be named 1606 // may be named
1607 String constructorName = constructor.displayName; 1607 String constructorName = constructor.displayName;
1608 if (!constructorName.isEmpty) { 1608 if (!constructorName.isEmpty) {
1609 proposalNameBuffer.write("."); 1609 proposalNameBuffer.append(".");
1610 proposalNameBuffer.write(constructorName); 1610 proposalNameBuffer.append(constructorName);
1611 } 1611 }
1612 // parameters 1612 // parameters
1613 _appendParameters(proposalNameBuffer, constructor.parameters, null); 1613 _appendParameters(proposalNameBuffer, constructor.parameters, null);
1614 // done 1614 // done
1615 return proposalNameBuffer.toString(); 1615 return proposalNameBuffer.toString();
1616 } 1616 }
1617 1617
1618 /** 1618 /**
1619 * Returns the [Type] with given name from the `dart:core` library.
1620 */
1621 DartType _getCoreType(String name) {
1622 List<LibraryElement> libraries = unitLibraryElement.importedLibraries;
1623 for (LibraryElement library in libraries) {
1624 if (library.isDartCore) {
1625 ClassElement classElement = library.getType(name);
1626 if (classElement != null) {
1627 return classElement.type;
1628 }
1629 return null;
1630 }
1631 }
1632 return null;
1633 }
1634
1635 Map<ParameterElement, String>
1636 _getDefaultValueMap(List<ParameterElement> parameters) {
1637 Map<ParameterElement, String> defaultSourceMap = {};
1638 Map<Source, String> sourceContentMap = {};
1639 for (ParameterElement parameter in parameters) {
1640 SourceRange valueRange = parameter.defaultValueRange;
1641 if (valueRange != null) {
1642 Source source = parameter.source;
1643 String sourceContent = sourceContentMap[source];
1644 if (sourceContent == null) {
1645 sourceContent = getSourceContent(parameter.context, source);
1646 sourceContentMap[source] = sourceContent;
1647 }
1648 String valueSource =
1649 sourceContent.substring(valueRange.offset, valueRange.end);
1650 defaultSourceMap[parameter] = valueSource;
1651 }
1652 }
1653 return defaultSourceMap;
1654 }
1655
1656 /**
1657 * Returns `true` if [node] is in static context.
1658 */
1659 bool _inStaticContext() {
1660 // constructor initializer cannot reference "this"
1661 if (node.getAncestor((node) => node is ConstructorInitializer) != null) {
1662 return true;
1663 }
1664 // field initializer cannot reference "this"
1665 if (node.getAncestor((node) => node is FieldDeclaration) != null) {
1666 return true;
1667 }
1668 // static method
1669 MethodDeclaration method = node.getAncestor((node) {
1670 return node is MethodDeclaration;
1671 });
1672 return method != null && method.isStatic;
1673 }
1674
1675 /**
1676 * Returns a possible return [Type], may be `null` if cannot be inferred.
1677 */
1678 DartType _inferReturnType(MethodInvocation invocation) {
1679 AstNode parent = invocation.parent;
1680 // myFunction();
1681 if (parent is ExpressionStatement) {
1682 return VoidTypeImpl.instance;
1683 }
1684 // return myFunction();
1685 if (parent is ReturnStatement) {
1686 ExecutableElement executable = getEnclosingExecutableElement(invocation);
1687 return executable != null ? executable.returnType : null;
1688 }
1689 // int v = myFunction();
1690 if (parent is VariableDeclaration) {
1691 VariableDeclaration variableDeclaration = parent;
1692 if (identical(variableDeclaration.initializer, invocation)) {
1693 VariableElement variableElement = variableDeclaration.element;
1694 if (variableElement != null) {
1695 return variableElement.type;
1696 }
1697 }
1698 }
1699 // v = myFunction();
1700 if (parent is AssignmentExpression) {
1701 AssignmentExpression assignment = parent;
1702 if (identical(assignment.rightHandSide, invocation)) {
1703 if (assignment.operator.type == TokenType.EQ) {
1704 // v = myFunction();
1705 Expression lhs = assignment.leftHandSide;
1706 if (lhs != null) {
1707 return lhs.bestType;
1708 }
1709 } else {
1710 // v += myFunction();
1711 MethodElement method = assignment.bestElement;
1712 if (method != null) {
1713 List<ParameterElement> parameters = method.parameters;
1714 if (parameters.length == 1) {
1715 return parameters[0].type;
1716 }
1717 }
1718 }
1719 }
1720 }
1721 // v + myFunction();
1722 if (parent is BinaryExpression) {
1723 BinaryExpression binary = parent;
1724 MethodElement method = binary.bestElement;
1725 if (method != null) {
1726 if (identical(binary.rightOperand, invocation)) {
1727 List<ParameterElement> parameters = method.parameters;
1728 return parameters.length == 1 ? parameters[0].type : null;
1729 }
1730 }
1731 }
1732 // foo( myFunction() );
1733 if (parent is ArgumentList) {
1734 ParameterElement parameter = invocation.bestParameterElement;
1735 return parameter != null ? parameter.type : null;
1736 }
1737 // bool
1738 {
1739 // assert( myFunction() );
1740 if (parent is AssertStatement) {
1741 AssertStatement statement = parent;
1742 if (identical(statement.condition, invocation)) {
1743 return coreTypeBool;
1744 }
1745 }
1746 // if ( myFunction() ) {}
1747 if (parent is IfStatement) {
1748 IfStatement statement = parent;
1749 if (identical(statement.condition, invocation)) {
1750 return coreTypeBool;
1751 }
1752 }
1753 // while ( myFunction() ) {}
1754 if (parent is WhileStatement) {
1755 WhileStatement statement = parent;
1756 if (identical(statement.condition, invocation)) {
1757 return coreTypeBool;
1758 }
1759 }
1760 // do {} while ( myFunction() );
1761 if (parent is DoStatement) {
1762 DoStatement statement = parent;
1763 if (identical(statement.condition, invocation)) {
1764 return coreTypeBool;
1765 }
1766 }
1767 // !myFunction()
1768 if (parent is PrefixExpression) {
1769 PrefixExpression prefixExpression = parent;
1770 if (prefixExpression.operator.type == TokenType.BANG) {
1771 return coreTypeBool;
1772 }
1773 }
1774 // binary expression '&&' or '||'
1775 if (parent is BinaryExpression) {
1776 BinaryExpression binaryExpression = parent;
1777 TokenType operatorType = binaryExpression.operator.type;
1778 if (operatorType == TokenType.AMPERSAND_AMPERSAND ||
1779 operatorType == TokenType.BAR_BAR) {
1780 return coreTypeBool;
1781 }
1782 }
1783 }
1784 // we don't know
1785 return null;
1786 }
1787
1788 // void _addLinkedPositionProposal(String group,
1789 // LinkedPositionProposal proposal) {
1790 // List<LinkedPositionProposal> nodeProposals = linkedPositionProposals[group ];
1791 // if (nodeProposals == null) {
1792 // nodeProposals = <LinkedPositionProposal>[];
1793 // linkedPositionProposals[group] = nodeProposals;
1794 // }
1795 // nodeProposals.add(proposal);
1796 // }
1797
1798 // /**
1799 // * Returns `true` if the given [ClassMember] is a part of a static method or
1800 // * a field initializer.
1801 // */
1802 // bool _inStaticMemberContext2(ClassMember member) {
1803 // if (member is MethodDeclaration) {
1804 // return member.isStatic;
1805 // }
1806 // // field initializer cannot reference "this"
1807 // if (member is FieldDeclaration) {
1808 // return true;
1809 // }
1810 // return false;
1811 // }
1812
1813 /**
1619 * Inserts the given [SourceBuilder] at its offset. 1814 * Inserts the given [SourceBuilder] at its offset.
1620 */ 1815 */
1621 void _insertBuilder(SourceBuilder builder) { 1816 void _insertBuilder(SourceBuilder builder) {
1622 String text = builder.toString(); 1817 String text = builder.toString();
1623 _addInsertEdit(builder.offset, text); 1818 _addInsertEdit(builder.offset, text);
1624 // add linked positions 1819 // add linked positions
1625 builder.linkedPositionGroups.forEach((LinkedPositionGroup group) { 1820 builder.linkedPositionGroups.forEach((LinkedPositionGroup group) {
1626 group.positions.forEach((Position position) { 1821 group.positions.forEach((Position position) {
1627 _addLinkedPosition2(group.id, position); 1822 _addLinkedPosition2(group.id, position);
1628 }); 1823 });
1629 }); 1824 });
1630 } 1825 }
1631 1826
1632 QuickFixProcessorImpl_NewConstructorLocation 1827 _ConstructorLocation
1633 _prepareNewConstructorLocation(ClassDeclaration classDeclaration, String e ol) { 1828 _prepareNewConstructorLocation(ClassDeclaration classDeclaration) {
1634 List<ClassMember> members = classDeclaration.members; 1829 List<ClassMember> members = classDeclaration.members;
1635 // find the last field/constructor 1830 // find the last field/constructor
1636 ClassMember lastFieldOrConstructor = null; 1831 ClassMember lastFieldOrConstructor = null;
1637 for (ClassMember member in members) { 1832 for (ClassMember member in members) {
1638 if (member is FieldDeclaration || member is ConstructorDeclaration) { 1833 if (member is FieldDeclaration || member is ConstructorDeclaration) {
1639 lastFieldOrConstructor = member; 1834 lastFieldOrConstructor = member;
1640 } else { 1835 } else {
1641 break; 1836 break;
1642 } 1837 }
1643 } 1838 }
1644 // after the field/constructor 1839 // after the field/constructor
1645 if (lastFieldOrConstructor != null) { 1840 if (lastFieldOrConstructor != null) {
1646 return new QuickFixProcessorImpl_NewConstructorLocation( 1841 return new _ConstructorLocation(
1647 "${eol}${eol}", 1842 "${eol}${eol}",
1648 lastFieldOrConstructor.end, 1843 lastFieldOrConstructor.end,
1649 ""); 1844 "");
1650 } 1845 }
1651 // at the beginning of the class 1846 // at the beginning of the class
1652 String suffix = members.isEmpty ? "" : eol; 1847 String suffix = members.isEmpty ? "" : eol;
1653 return new QuickFixProcessorImpl_NewConstructorLocation( 1848 return new _ConstructorLocation(
1654 eol, 1849 eol,
1655 classDeclaration.leftBracket.end, 1850 classDeclaration.leftBracket.end,
1656 suffix); 1851 suffix);
1657 } 1852 }
1658 1853
1659 /** 1854 /**
1660 * Removes any [ParenthesizedExpression] enclosing [expr]. 1855 * Removes any [ParenthesizedExpression] enclosing [expr].
1661 * 1856 *
1662 * [exprPrecedence] - the effective precedence of [expr]. 1857 * [exprPrecedence] - the effective precedence of [expr].
1663 */ 1858 */
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1721 return false; 1916 return false;
1722 } 1917 }
1723 } 1918 }
1724 1919
1725 1920
1726 /** 1921 /**
1727 * Describes the location for a newly created [ConstructorDeclaration]. 1922 * Describes the location for a newly created [ConstructorDeclaration].
1728 * 1923 *
1729 * TODO(scheglov) rename 1924 * TODO(scheglov) rename
1730 */ 1925 */
1731 class QuickFixProcessorImpl_NewConstructorLocation { 1926 class _ConstructorLocation {
1732 final String _prefix; 1927 final String _prefix;
1733 final int _offset; 1928 final int _offset;
1734 final String _suffix; 1929 final String _suffix;
1735 1930
1736 QuickFixProcessorImpl_NewConstructorLocation(this._prefix, this._offset, 1931 _ConstructorLocation(this._prefix, this._offset, this._suffix);
1737 this._suffix);
1738 } 1932 }
OLDNEW
« no previous file with comments | « pkg/analysis_services/lib/correction/fix.dart ('k') | pkg/analysis_services/lib/src/correction/source_buffer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698