| 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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  184           result.add(classMemberElement.displayName); |  184           result.add(classMemberElement.displayName); | 
|  185         } |  185         } | 
|  186       } |  186       } | 
|  187     } |  187     } | 
|  188   } |  188   } | 
|  189   // done |  189   // done | 
|  190   return result; |  190   return result; | 
|  191 } |  191 } | 
|  192  |  192  | 
|  193 /** |  193 /** | 
 |  194  * Completes with the resolved [CompilationUnit] that contains the [element]. | 
 |  195  */ | 
 |  196 typedef Future<CompilationUnit> GetResolvedUnitContainingElement( | 
 |  197     Element element); | 
 |  198  | 
 |  199 /** | 
|  194  * [InlineMethodRefactoring] implementation. |  200  * [InlineMethodRefactoring] implementation. | 
|  195  */ |  201  */ | 
|  196 class InlineMethodRefactoringImpl extends RefactoringImpl |  202 class InlineMethodRefactoringImpl extends RefactoringImpl | 
|  197     implements InlineMethodRefactoring { |  203     implements InlineMethodRefactoring { | 
|  198   final SearchEngine searchEngine; |  204   final SearchEngine searchEngine; | 
 |  205   final GetResolvedUnitContainingElement getResolvedUnit; | 
|  199   final CompilationUnit unit; |  206   final CompilationUnit unit; | 
|  200   final int offset; |  207   final int offset; | 
|  201   CorrectionUtils utils; |  208   CorrectionUtils utils; | 
|  202   SourceChange change; |  209   SourceChange change; | 
|  203  |  210  | 
|  204   bool isDeclaration = false; |  211   bool isDeclaration = false; | 
|  205   bool deleteSource = false; |  212   bool deleteSource = false; | 
|  206   bool inlineAll = true; |  213   bool inlineAll = true; | 
|  207  |  214  | 
|  208   ExecutableElement _methodElement; |  215   ExecutableElement _methodElement; | 
|  209   bool _isAccessor; |  216   bool _isAccessor; | 
|  210   CompilationUnit _methodUnit; |  217   CompilationUnit _methodUnit; | 
|  211   CorrectionUtils _methodUtils; |  218   CorrectionUtils _methodUtils; | 
|  212   AstNode _methodNode; |  219   AstNode _methodNode; | 
|  213   FormalParameterList _methodParameters; |  220   FormalParameterList _methodParameters; | 
|  214   FunctionBody _methodBody; |  221   FunctionBody _methodBody; | 
|  215   Expression _methodExpression; |  222   Expression _methodExpression; | 
|  216   _SourcePart _methodExpressionPart; |  223   _SourcePart _methodExpressionPart; | 
|  217   _SourcePart _methodStatementsPart; |  224   _SourcePart _methodStatementsPart; | 
|  218   List<_ReferenceProcessor> _referenceProcessors = []; |  225   List<_ReferenceProcessor> _referenceProcessors = []; | 
|  219   Set<FunctionBody> _alreadyMadeAsync = new Set<FunctionBody>(); |  226   Set<FunctionBody> _alreadyMadeAsync = new Set<FunctionBody>(); | 
|  220  |  227  | 
|  221   InlineMethodRefactoringImpl(this.searchEngine, this.unit, this.offset) { |  228   InlineMethodRefactoringImpl( | 
 |  229       this.searchEngine, this.getResolvedUnit, this.unit, this.offset) { | 
|  222     utils = new CorrectionUtils(unit); |  230     utils = new CorrectionUtils(unit); | 
|  223   } |  231   } | 
|  224  |  232  | 
|  225   @override |  233   @override | 
|  226   String get className { |  234   String get className { | 
|  227     if (_methodElement == null) { |  235     if (_methodElement == null) { | 
|  228       return null; |  236       return null; | 
|  229     } |  237     } | 
|  230     Element classElement = _methodElement.enclosingElement; |  238     Element classElement = _methodElement.enclosingElement; | 
|  231     if (classElement is ClassElement) { |  239     if (classElement is ClassElement) { | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  272           change, _methodElement, newSourceEdit_range(linesRange, '')); |  280           change, _methodElement, newSourceEdit_range(linesRange, '')); | 
|  273     } |  281     } | 
|  274     // done |  282     // done | 
|  275     return new Future.value(result); |  283     return new Future.value(result); | 
|  276   } |  284   } | 
|  277  |  285  | 
|  278   @override |  286   @override | 
|  279   Future<RefactoringStatus> checkInitialConditions() async { |  287   Future<RefactoringStatus> checkInitialConditions() async { | 
|  280     RefactoringStatus result = new RefactoringStatus(); |  288     RefactoringStatus result = new RefactoringStatus(); | 
|  281     // prepare method information |  289     // prepare method information | 
|  282     result.addStatus(_prepareMethod()); |  290     result.addStatus(await _prepareMethod()); | 
|  283     if (result.hasFatalError) { |  291     if (result.hasFatalError) { | 
|  284       return new Future<RefactoringStatus>.value(result); |  292       return new Future<RefactoringStatus>.value(result); | 
|  285     } |  293     } | 
|  286     // maybe operator |  294     // maybe operator | 
|  287     if (_methodElement.isOperator) { |  295     if (_methodElement.isOperator) { | 
|  288       result = new RefactoringStatus.fatal('Cannot inline operator.'); |  296       result = new RefactoringStatus.fatal('Cannot inline operator.'); | 
|  289       return new Future<RefactoringStatus>.value(result); |  297       return new Future<RefactoringStatus>.value(result); | 
|  290     } |  298     } | 
|  291     // maybe [a]sync* |  299     // maybe [a]sync* | 
|  292     if (_methodElement.isGenerator) { |  300     if (_methodElement.isGenerator) { | 
|  293       result = new RefactoringStatus.fatal('Cannot inline a generator.'); |  301       result = new RefactoringStatus.fatal('Cannot inline a generator.'); | 
|  294       return new Future<RefactoringStatus>.value(result); |  302       return new Future<RefactoringStatus>.value(result); | 
|  295     } |  303     } | 
|  296     // analyze method body |  304     // analyze method body | 
|  297     result.addStatus(_prepareMethodParts()); |  305     result.addStatus(_prepareMethodParts()); | 
|  298     // process references |  306     // process references | 
|  299     List<SearchMatch> references = |  307     List<SearchMatch> references = | 
|  300         await searchEngine.searchReferences(_methodElement); |  308         await searchEngine.searchReferences(_methodElement); | 
|  301     _referenceProcessors.clear(); |  309     _referenceProcessors.clear(); | 
|  302     for (SearchMatch reference in references) { |  310     for (SearchMatch reference in references) { | 
|  303       _ReferenceProcessor processor = new _ReferenceProcessor(this, reference); |  311       _ReferenceProcessor processor = new _ReferenceProcessor(this, reference); | 
 |  312       await processor.init(); | 
|  304       _referenceProcessors.add(processor); |  313       _referenceProcessors.add(processor); | 
|  305     } |  314     } | 
|  306     return result; |  315     return result; | 
|  307   } |  316   } | 
|  308  |  317  | 
|  309   @override |  318   @override | 
|  310   Future<SourceChange> createChange() { |  319   Future<SourceChange> createChange() { | 
|  311     return new Future.value(change); |  320     return new Future.value(change); | 
|  312   } |  321   } | 
|  313  |  322  | 
|  314   @override |  323   @override | 
|  315   bool requiresPreview() => false; |  324   bool requiresPreview() => false; | 
|  316  |  325  | 
|  317   _SourcePart _createSourcePart(SourceRange range) { |  326   _SourcePart _createSourcePart(SourceRange range) { | 
|  318     String source = _methodUtils.getRangeText(range); |  327     String source = _methodUtils.getRangeText(range); | 
|  319     String prefix = getLinePrefix(source); |  328     String prefix = getLinePrefix(source); | 
|  320     _SourcePart result = new _SourcePart(range.offset, source, prefix); |  329     _SourcePart result = new _SourcePart(range.offset, source, prefix); | 
|  321     // remember parameters and variables occurrences |  330     // remember parameters and variables occurrences | 
|  322     _methodUnit.accept(new _VariablesVisitor(_methodElement, range, result)); |  331     _methodUnit.accept(new _VariablesVisitor(_methodElement, range, result)); | 
|  323     // done |  332     // done | 
|  324     return result; |  333     return result; | 
|  325   } |  334   } | 
|  326  |  335  | 
|  327   /** |  336   /** | 
|  328    * Initializes [_methodElement] and related fields. |  337    * Initializes [_methodElement] and related fields. | 
|  329    */ |  338    */ | 
|  330   RefactoringStatus _prepareMethod() { |  339   Future<RefactoringStatus> _prepareMethod() async { | 
|  331     _methodElement = null; |  340     _methodElement = null; | 
|  332     _methodParameters = null; |  341     _methodParameters = null; | 
|  333     _methodBody = null; |  342     _methodBody = null; | 
|  334     deleteSource = false; |  343     deleteSource = false; | 
|  335     inlineAll = false; |  344     inlineAll = false; | 
|  336     // prepare for failure |  345     // prepare for failure | 
|  337     RefactoringStatus fatalStatus = new RefactoringStatus.fatal( |  346     RefactoringStatus fatalStatus = new RefactoringStatus.fatal( | 
|  338         'Method declaration or reference must be selected to activate this refac
     toring.'); |  347         'Method declaration or reference must be selected to activate this refac
     toring.'); | 
|  339     // prepare selected SimpleIdentifier |  348     // prepare selected SimpleIdentifier | 
|  340     AstNode node = new NodeLocator(offset).searchWithin(unit); |  349     AstNode node = new NodeLocator(offset).searchWithin(unit); | 
|  341     if (node is! SimpleIdentifier) { |  350     if (node is! SimpleIdentifier) { | 
|  342       return fatalStatus; |  351       return fatalStatus; | 
|  343     } |  352     } | 
|  344     SimpleIdentifier identifier = node as SimpleIdentifier; |  353     SimpleIdentifier identifier = node as SimpleIdentifier; | 
|  345     // prepare selected ExecutableElement |  354     // prepare selected ExecutableElement | 
|  346     Element element = identifier.bestElement; |  355     Element element = identifier.bestElement; | 
|  347     if (element is! ExecutableElement) { |  356     if (element is! ExecutableElement) { | 
|  348       return fatalStatus; |  357       return fatalStatus; | 
|  349     } |  358     } | 
|  350     if (element.isSynthetic) { |  359     if (element.isSynthetic) { | 
|  351       return fatalStatus; |  360       return fatalStatus; | 
|  352     } |  361     } | 
|  353     _methodElement = element as ExecutableElement; |  362     _methodElement = element as ExecutableElement; | 
|  354     _isAccessor = element is PropertyAccessorElement; |  363     _isAccessor = element is PropertyAccessorElement; | 
|  355     _methodUnit = element.unit; |  364     _methodUnit = await getResolvedUnit(element); | 
|  356     _methodUtils = new CorrectionUtils(_methodUnit); |  365     _methodUtils = new CorrectionUtils(_methodUnit); | 
|  357     // class member |  366     // class member | 
|  358     bool isClassMember = element.enclosingElement is ClassElement; |  367     bool isClassMember = element.enclosingElement is ClassElement; | 
|  359     if (element is MethodElement || _isAccessor && isClassMember) { |  368     if (element is MethodElement || _isAccessor && isClassMember) { | 
|  360       MethodDeclaration methodDeclaration = element.computeNode(); |  369       MethodDeclaration methodDeclaration = element.computeNode(); | 
|  361       _methodNode = methodDeclaration; |  370       _methodNode = methodDeclaration; | 
|  362       _methodParameters = methodDeclaration.parameters; |  371       _methodParameters = methodDeclaration.parameters; | 
|  363       _methodBody = methodDeclaration.body; |  372       _methodBody = methodDeclaration.body; | 
|  364       // prepare mode |  373       // prepare mode | 
|  365       isDeclaration = node == methodDeclaration.name; |  374       isDeclaration = node == methodDeclaration.name; | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  428   final int parentPrecedence; |  437   final int parentPrecedence; | 
|  429   final SourceRange range; |  438   final SourceRange range; | 
|  430   _ParameterOccurrence(this.parentPrecedence, this.range); |  439   _ParameterOccurrence(this.parentPrecedence, this.range); | 
|  431 } |  440 } | 
|  432  |  441  | 
|  433 /** |  442 /** | 
|  434  * Processor for single [SearchMatch] reference to [methodElement]. |  443  * Processor for single [SearchMatch] reference to [methodElement]. | 
|  435  */ |  444  */ | 
|  436 class _ReferenceProcessor { |  445 class _ReferenceProcessor { | 
|  437   final InlineMethodRefactoringImpl ref; |  446   final InlineMethodRefactoringImpl ref; | 
 |  447   final SearchMatch reference; | 
|  438  |  448  | 
|  439   Element refElement; |  449   Element refElement; | 
|  440   CorrectionUtils _refUtils; |  450   CorrectionUtils _refUtils; | 
|  441   SimpleIdentifier _node; |  451   SimpleIdentifier _node; | 
|  442   SourceRange _refLineRange; |  452   SourceRange _refLineRange; | 
|  443   String _refPrefix; |  453   String _refPrefix; | 
|  444  |  454  | 
|  445   _ReferenceProcessor(this.ref, SearchMatch reference) { |  455   _ReferenceProcessor(this.ref, this.reference); | 
 |  456  | 
 |  457   Future<Null> init() async { | 
|  446     refElement = reference.element; |  458     refElement = reference.element; | 
|  447     // prepare CorrectionUtils |  459     // prepare CorrectionUtils | 
|  448     CompilationUnit refUnit = refElement.unit; |  460     CompilationUnit refUnit = await ref.getResolvedUnit(refElement); | 
|  449     _refUtils = new CorrectionUtils(refUnit); |  461     _refUtils = new CorrectionUtils(refUnit); | 
|  450     // prepare node and environment |  462     // prepare node and environment | 
|  451     _node = _refUtils.findNode(reference.sourceRange.offset); |  463     _node = _refUtils.findNode(reference.sourceRange.offset); | 
|  452     Statement refStatement = _node.getAncestor((node) => node is Statement); |  464     Statement refStatement = _node.getAncestor((node) => node is Statement); | 
|  453     if (refStatement != null) { |  465     if (refStatement != null) { | 
|  454       _refLineRange = _refUtils.getLinesRangeStatements([refStatement]); |  466       _refLineRange = _refUtils.getLinesRangeStatements([refStatement]); | 
|  455       _refPrefix = _refUtils.getNodePrefix(refStatement); |  467       _refPrefix = _refUtils.getNodePrefix(refStatement); | 
|  456     } else { |  468     } else { | 
|  457       _refLineRange = null; |  469       _refLineRange = null; | 
|  458       _refPrefix = _refUtils.getLinePrefix(_node.offset); |  470       _refPrefix = _refUtils.getLinePrefix(_node.offset); | 
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  858   } |  870   } | 
|  859  |  871  | 
|  860   void _addVariable(SimpleIdentifier node) { |  872   void _addVariable(SimpleIdentifier node) { | 
|  861     VariableElement variableElement = getLocalVariableElement(node); |  873     VariableElement variableElement = getLocalVariableElement(node); | 
|  862     if (variableElement != null) { |  874     if (variableElement != null) { | 
|  863       SourceRange nodeRange = rangeNode(node); |  875       SourceRange nodeRange = rangeNode(node); | 
|  864       result.addVariable(variableElement, nodeRange); |  876       result.addVariable(variableElement, nodeRange); | 
|  865     } |  877     } | 
|  866   } |  878   } | 
|  867 } |  879 } | 
| OLD | NEW |