| 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 library services.src.refactoring.inline_method; | 5 library services.src.refactoring.inline_method; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/protocol_server.dart' hide Element; | 9 import 'package:analysis_server/src/protocol_server.dart' hide Element; |
| 10 import 'package:analysis_server/src/services/correction/source_range.dart'; | 10 import 'package:analysis_server/src/services/correction/source_range.dart'; |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 | 192 |
| 193 /** | 193 /** |
| 194 * [InlineMethodRefactoring] implementation. | 194 * [InlineMethodRefactoring] implementation. |
| 195 */ | 195 */ |
| 196 class InlineMethodRefactoringImpl extends RefactoringImpl | 196 class InlineMethodRefactoringImpl extends RefactoringImpl |
| 197 implements InlineMethodRefactoring { | 197 implements InlineMethodRefactoring { |
| 198 final SearchEngine searchEngine; | 198 final SearchEngine searchEngine; |
| 199 final GetResolvedUnit getResolvedUnit; | 199 final GetResolvedUnit getResolvedUnit; |
| 200 final CompilationUnit unit; | 200 final CompilationUnit unit; |
| 201 final int offset; | 201 final int offset; |
| 202 _UnitCache _unitCache; |
| 202 CorrectionUtils utils; | 203 CorrectionUtils utils; |
| 203 SourceChange change; | 204 SourceChange change; |
| 204 | 205 |
| 205 bool isDeclaration = false; | 206 bool isDeclaration = false; |
| 206 bool deleteSource = false; | 207 bool deleteSource = false; |
| 207 bool inlineAll = true; | 208 bool inlineAll = true; |
| 208 | 209 |
| 209 ExecutableElement _methodElement; | 210 ExecutableElement _methodElement; |
| 210 bool _isAccessor; | 211 bool _isAccessor; |
| 211 CompilationUnit _methodUnit; | 212 CompilationUnit _methodUnit; |
| 212 CorrectionUtils _methodUtils; | 213 CorrectionUtils _methodUtils; |
| 213 AstNode _methodNode; | 214 AstNode _methodNode; |
| 214 FormalParameterList _methodParameters; | 215 FormalParameterList _methodParameters; |
| 215 FunctionBody _methodBody; | 216 FunctionBody _methodBody; |
| 216 Expression _methodExpression; | 217 Expression _methodExpression; |
| 217 _SourcePart _methodExpressionPart; | 218 _SourcePart _methodExpressionPart; |
| 218 _SourcePart _methodStatementsPart; | 219 _SourcePart _methodStatementsPart; |
| 219 List<_ReferenceProcessor> _referenceProcessors = []; | 220 List<_ReferenceProcessor> _referenceProcessors = []; |
| 220 Set<FunctionBody> _alreadyMadeAsync = new Set<FunctionBody>(); | 221 Set<FunctionBody> _alreadyMadeAsync = new Set<FunctionBody>(); |
| 221 | 222 |
| 222 InlineMethodRefactoringImpl( | 223 InlineMethodRefactoringImpl( |
| 223 this.searchEngine, this.getResolvedUnit, this.unit, this.offset) { | 224 this.searchEngine, this.getResolvedUnit, this.unit, this.offset) { |
| 225 _unitCache = new _UnitCache(getResolvedUnit, unit); |
| 224 utils = new CorrectionUtils(unit); | 226 utils = new CorrectionUtils(unit); |
| 225 } | 227 } |
| 226 | 228 |
| 227 @override | 229 @override |
| 228 String get className { | 230 String get className { |
| 229 if (_methodElement == null) { | 231 if (_methodElement == null) { |
| 230 return null; | 232 return null; |
| 231 } | 233 } |
| 232 Element classElement = _methodElement.enclosingElement; | 234 Element classElement = _methodElement.enclosingElement; |
| 233 if (classElement is ClassElement) { | 235 if (classElement is ClassElement) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 } | 312 } |
| 311 | 313 |
| 312 @override | 314 @override |
| 313 Future<SourceChange> createChange() { | 315 Future<SourceChange> createChange() { |
| 314 return new Future.value(change); | 316 return new Future.value(change); |
| 315 } | 317 } |
| 316 | 318 |
| 317 @override | 319 @override |
| 318 bool requiresPreview() => false; | 320 bool requiresPreview() => false; |
| 319 | 321 |
| 322 Future<FunctionDeclaration> _computeFunctionDeclaration() async { |
| 323 CompilationUnit unit = await _unitCache.getUnit(_methodElement); |
| 324 return new NodeLocator(_methodElement.nameOffset) |
| 325 .searchWithin(unit) |
| 326 .getAncestor((n) => n is FunctionDeclaration) as FunctionDeclaration; |
| 327 } |
| 328 |
| 329 Future<MethodDeclaration> _computeMethodDeclaration() async { |
| 330 CompilationUnit unit = await _unitCache.getUnit(_methodElement); |
| 331 return new NodeLocator(_methodElement.nameOffset) |
| 332 .searchWithin(unit) |
| 333 .getAncestor((n) => n is MethodDeclaration) as MethodDeclaration; |
| 334 } |
| 335 |
| 320 _SourcePart _createSourcePart(SourceRange range) { | 336 _SourcePart _createSourcePart(SourceRange range) { |
| 321 String source = _methodUtils.getRangeText(range); | 337 String source = _methodUtils.getRangeText(range); |
| 322 String prefix = getLinePrefix(source); | 338 String prefix = getLinePrefix(source); |
| 323 _SourcePart result = new _SourcePart(range.offset, source, prefix); | 339 _SourcePart result = new _SourcePart(range.offset, source, prefix); |
| 324 // remember parameters and variables occurrences | 340 // remember parameters and variables occurrences |
| 325 _methodUnit.accept(new _VariablesVisitor(_methodElement, range, result)); | 341 _methodUnit.accept(new _VariablesVisitor(_methodElement, range, result)); |
| 326 // done | 342 // done |
| 327 return result; | 343 return result; |
| 328 } | 344 } |
| 329 | 345 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 348 // prepare selected ExecutableElement | 364 // prepare selected ExecutableElement |
| 349 Element element = identifier.bestElement; | 365 Element element = identifier.bestElement; |
| 350 if (element is! ExecutableElement) { | 366 if (element is! ExecutableElement) { |
| 351 return fatalStatus; | 367 return fatalStatus; |
| 352 } | 368 } |
| 353 if (element.isSynthetic) { | 369 if (element.isSynthetic) { |
| 354 return fatalStatus; | 370 return fatalStatus; |
| 355 } | 371 } |
| 356 _methodElement = element as ExecutableElement; | 372 _methodElement = element as ExecutableElement; |
| 357 _isAccessor = element is PropertyAccessorElement; | 373 _isAccessor = element is PropertyAccessorElement; |
| 358 _methodUnit = await getResolvedUnit(element); | 374 _methodUnit = await _unitCache.getUnit(element); |
| 359 _methodUtils = new CorrectionUtils(_methodUnit); | 375 _methodUtils = new CorrectionUtils(_methodUnit); |
| 360 // class member | 376 // class member |
| 361 bool isClassMember = element.enclosingElement is ClassElement; | 377 bool isClassMember = element.enclosingElement is ClassElement; |
| 362 if (element is MethodElement || _isAccessor && isClassMember) { | 378 if (element is MethodElement || _isAccessor && isClassMember) { |
| 363 MethodDeclaration methodDeclaration = element.computeNode(); | 379 MethodDeclaration methodDeclaration = await _computeMethodDeclaration(); |
| 364 _methodNode = methodDeclaration; | 380 _methodNode = methodDeclaration; |
| 365 _methodParameters = methodDeclaration.parameters; | 381 _methodParameters = methodDeclaration.parameters; |
| 366 _methodBody = methodDeclaration.body; | 382 _methodBody = methodDeclaration.body; |
| 367 // prepare mode | 383 // prepare mode |
| 368 isDeclaration = node == methodDeclaration.name; | 384 isDeclaration = node == methodDeclaration.name; |
| 369 deleteSource = isDeclaration; | 385 deleteSource = isDeclaration; |
| 370 inlineAll = deleteSource; | 386 inlineAll = deleteSource; |
| 371 return new RefactoringStatus(); | 387 return new RefactoringStatus(); |
| 372 } | 388 } |
| 373 // unit member | 389 // unit member |
| 374 bool isUnitMember = element.enclosingElement is CompilationUnitElement; | 390 bool isUnitMember = element.enclosingElement is CompilationUnitElement; |
| 375 if (element is FunctionElement || _isAccessor && isUnitMember) { | 391 if (element is FunctionElement || _isAccessor && isUnitMember) { |
| 376 FunctionDeclaration functionDeclaration = element.computeNode(); | 392 FunctionDeclaration functionDeclaration = |
| 393 await _computeFunctionDeclaration(); |
| 377 _methodNode = functionDeclaration; | 394 _methodNode = functionDeclaration; |
| 378 _methodParameters = functionDeclaration.functionExpression.parameters; | 395 _methodParameters = functionDeclaration.functionExpression.parameters; |
| 379 _methodBody = functionDeclaration.functionExpression.body; | 396 _methodBody = functionDeclaration.functionExpression.body; |
| 380 // prepare mode | 397 // prepare mode |
| 381 isDeclaration = node == functionDeclaration.name; | 398 isDeclaration = node == functionDeclaration.name; |
| 382 deleteSource = isDeclaration; | 399 deleteSource = isDeclaration; |
| 383 inlineAll = deleteSource; | 400 inlineAll = deleteSource; |
| 384 return new RefactoringStatus(); | 401 return new RefactoringStatus(); |
| 385 } | 402 } |
| 386 // OK | 403 // OK |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 CorrectionUtils _refUtils; | 461 CorrectionUtils _refUtils; |
| 445 SimpleIdentifier _node; | 462 SimpleIdentifier _node; |
| 446 SourceRange _refLineRange; | 463 SourceRange _refLineRange; |
| 447 String _refPrefix; | 464 String _refPrefix; |
| 448 | 465 |
| 449 _ReferenceProcessor(this.ref, this.reference); | 466 _ReferenceProcessor(this.ref, this.reference); |
| 450 | 467 |
| 451 Future<Null> init() async { | 468 Future<Null> init() async { |
| 452 refElement = reference.element; | 469 refElement = reference.element; |
| 453 // prepare CorrectionUtils | 470 // prepare CorrectionUtils |
| 454 CompilationUnit refUnit = await ref.getResolvedUnit(refElement); | 471 CompilationUnit refUnit = await ref._unitCache.getUnit(refElement); |
| 455 _refUtils = new CorrectionUtils(refUnit); | 472 _refUtils = new CorrectionUtils(refUnit); |
| 456 // prepare node and environment | 473 // prepare node and environment |
| 457 _node = _refUtils.findNode(reference.sourceRange.offset); | 474 _node = _refUtils.findNode(reference.sourceRange.offset); |
| 458 Statement refStatement = _node.getAncestor((node) => node is Statement); | 475 Statement refStatement = _node.getAncestor((node) => node is Statement); |
| 459 if (refStatement != null) { | 476 if (refStatement != null) { |
| 460 _refLineRange = _refUtils.getLinesRangeStatements([refStatement]); | 477 _refLineRange = _refUtils.getLinesRangeStatements([refStatement]); |
| 461 _refPrefix = _refUtils.getNodePrefix(refStatement); | 478 _refPrefix = _refUtils.getNodePrefix(refStatement); |
| 462 } else { | 479 } else { |
| 463 _refLineRange = null; | 480 _refLineRange = null; |
| 464 _refPrefix = _refUtils.getLinePrefix(_node.offset); | 481 _refPrefix = _refUtils.getLinePrefix(_node.offset); |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 List<SourceRange> ranges = _variables[element]; | 781 List<SourceRange> ranges = _variables[element]; |
| 765 if (ranges == null) { | 782 if (ranges == null) { |
| 766 ranges = []; | 783 ranges = []; |
| 767 _variables[element] = ranges; | 784 _variables[element] = ranges; |
| 768 } | 785 } |
| 769 range = rangeFromBase(range, _base); | 786 range = rangeFromBase(range, _base); |
| 770 ranges.add(range); | 787 ranges.add(range); |
| 771 } | 788 } |
| 772 } | 789 } |
| 773 | 790 |
| 791 class _UnitCache { |
| 792 final GetResolvedUnit getResolvedUnit; |
| 793 final Map<CompilationUnitElement, CompilationUnit> map = {}; |
| 794 |
| 795 _UnitCache(this.getResolvedUnit, CompilationUnit unit) { |
| 796 map[unit.element] = unit; |
| 797 } |
| 798 |
| 799 Future<CompilationUnit> getUnit(Element element) async { |
| 800 Element unitElement = |
| 801 element.getAncestor((e) => e is CompilationUnitElement); |
| 802 CompilationUnit unit = map[unitElement]; |
| 803 if (unit == null) { |
| 804 unit = unitElement.unit; |
| 805 map[unitElement] = unit; |
| 806 } |
| 807 return unit; |
| 808 } |
| 809 } |
| 810 |
| 774 /** | 811 /** |
| 775 * A visitor that fills [_SourcePart] with fields, parameters and variables. | 812 * A visitor that fills [_SourcePart] with fields, parameters and variables. |
| 776 */ | 813 */ |
| 777 class _VariablesVisitor extends GeneralizingAstVisitor { | 814 class _VariablesVisitor extends GeneralizingAstVisitor { |
| 778 /** | 815 /** |
| 779 * The [ExecutableElement] being inlined. | 816 * The [ExecutableElement] being inlined. |
| 780 */ | 817 */ |
| 781 final ExecutableElement methodElement; | 818 final ExecutableElement methodElement; |
| 782 | 819 |
| 783 /** | 820 /** |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 } | 901 } |
| 865 | 902 |
| 866 void _addVariable(SimpleIdentifier node) { | 903 void _addVariable(SimpleIdentifier node) { |
| 867 VariableElement variableElement = getLocalVariableElement(node); | 904 VariableElement variableElement = getLocalVariableElement(node); |
| 868 if (variableElement != null) { | 905 if (variableElement != null) { |
| 869 SourceRange nodeRange = rangeNode(node); | 906 SourceRange nodeRange = rangeNode(node); |
| 870 result.addVariable(variableElement, nodeRange); | 907 result.addVariable(variableElement, nodeRange); |
| 871 } | 908 } |
| 872 } | 909 } |
| 873 } | 910 } |
| OLD | NEW |