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

Unified Diff: pkg/analysis_server/lib/src/edit/edit_domain.dart

Issue 2262393003: 'Extract Local' and 'Inline Local' refactoring need only single file analysis. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analysis_server/test/analysis_abstract.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analysis_server/lib/src/edit/edit_domain.dart
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 260f67f6ed971bb69dab98b71c0c4da3d0137cfc..4e3c02634576efd814ab3b9e57f7f80546d2dece 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -26,8 +26,11 @@ import 'package:analyzer/src/generated/engine.dart' as engine;
import 'package:analyzer/src/generated/error.dart' as engine;
import 'package:analyzer/src/generated/parser.dart' as engine;
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/task/dart.dart';
import 'package:dart_style/dart_style.dart';
+int test_resetCount = 0;
+
bool test_simulateRefactoringException_change = false;
bool test_simulateRefactoringException_final = false;
bool test_simulateRefactoringException_init = false;
@@ -376,7 +379,7 @@ class _RefactoringManager {
final AnalysisServer server;
final SearchEngine searchEngine;
- StreamSubscription onAnalysisStartedSubscription;
+ StreamSubscription subscriptionToReset;
RefactoringKind kind;
String file;
@@ -392,7 +395,6 @@ class _RefactoringManager {
EditGetRefactoringResult result;
_RefactoringManager(this.server, this.searchEngine) {
- onAnalysisStartedSubscription = server.onAnalysisStarted.listen(_reset);
_reset();
}
@@ -422,7 +424,8 @@ class _RefactoringManager {
* Cancels processing of the current request and cleans up.
*/
void cancel() {
- onAnalysisStartedSubscription.cancel();
+ subscriptionToReset?.cancel();
+ subscriptionToReset = null;
server.sendResponse(new Response.refactoringRequestCancelled(request));
request = null;
}
@@ -492,6 +495,29 @@ class _RefactoringManager {
});
}
+ /**
+ * Perform enough analysis to be able to perform refactoring of the given
+ * [kind] in the given [file].
+ */
+ Future<Null> _analyzeForRefactoring(String file, RefactoringKind kind) async {
+ // "Extract Local" and "Inline Local" refactorings need only local analysis.
+ if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE ||
+ kind == RefactoringKind.INLINE_LOCAL_VARIABLE) {
+ ContextSourcePair pair = server.getContextSourcePair(file);
+ engine.AnalysisContext context = pair.context;
+ Source source = pair.source;
+ if (context != null && source != null) {
+ if (context.computeResult(source, SOURCE_KIND) == SourceKind.LIBRARY) {
+ await context.computeResolvedCompilationUnitAsync(source, source);
+ return;
+ }
+ }
+ }
+ // A refactoring for which we cannot optimize analysis.
+ // So, wait for full analysis.
+ await server.onAnalysisComplete;
+ }
+
void _checkForReset_afterCreateChange() {
if (test_simulateRefactoringReset_afterCreateChange) {
_reset();
@@ -525,7 +551,7 @@ class _RefactoringManager {
*/
Future _init(
RefactoringKind kind, String file, int offset, int length) async {
- await server.onAnalysisComplete;
+ await _analyzeForRefactoring(file, kind);
// check if we can continue with the existing Refactoring instance
if (this.kind == kind &&
this.file == file &&
@@ -548,6 +574,7 @@ class _RefactoringManager {
if (elements.isNotEmpty) {
Element element = elements[0];
if (element is ExecutableElement) {
+ _resetOnAnalysisStarted();
refactoring =
new ConvertGetterToMethodRefactoring(searchEngine, element);
}
@@ -558,6 +585,7 @@ class _RefactoringManager {
if (elements.isNotEmpty) {
Element element = elements[0];
if (element is ExecutableElement) {
+ _resetOnAnalysisStarted();
refactoring =
new ConvertMethodToGetterRefactoring(searchEngine, element);
}
@@ -566,6 +594,7 @@ class _RefactoringManager {
if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) {
List<CompilationUnit> units = server.getResolvedCompilationUnits(file);
if (units.isNotEmpty) {
+ _resetOnFileResolutionChanged(file);
refactoring = new ExtractLocalRefactoring(units[0], offset, length);
feedback = new ExtractLocalVariableFeedback(
<String>[], <int>[], <int>[],
@@ -576,6 +605,7 @@ class _RefactoringManager {
if (kind == RefactoringKind.EXTRACT_METHOD) {
List<CompilationUnit> units = server.getResolvedCompilationUnits(file);
if (units.isNotEmpty) {
+ _resetOnAnalysisStarted();
refactoring = new ExtractMethodRefactoring(
searchEngine, units[0], offset, length);
feedback = new ExtractMethodFeedback(offset, length, '', <String>[],
@@ -585,6 +615,7 @@ class _RefactoringManager {
if (kind == RefactoringKind.INLINE_LOCAL_VARIABLE) {
List<CompilationUnit> units = server.getResolvedCompilationUnits(file);
if (units.isNotEmpty) {
+ _resetOnFileResolutionChanged(file);
refactoring =
new InlineLocalRefactoring(searchEngine, units[0], offset);
}
@@ -592,11 +623,13 @@ class _RefactoringManager {
if (kind == RefactoringKind.INLINE_METHOD) {
List<CompilationUnit> units = server.getResolvedCompilationUnits(file);
if (units.isNotEmpty) {
+ _resetOnAnalysisStarted();
refactoring =
new InlineMethodRefactoring(searchEngine, units[0], offset);
}
}
if (kind == RefactoringKind.MOVE_FILE) {
+ _resetOnAnalysisStarted();
ContextSourcePair contextSource = server.getContextSourcePair(file);
engine.AnalysisContext context = contextSource.context;
Source source = contextSource.source;
@@ -619,6 +652,7 @@ class _RefactoringManager {
element = constructor.staticElement;
}
// do create the refactoring
+ _resetOnAnalysisStarted();
refactoring = new RenameRefactoring(searchEngine, element);
feedback =
new RenameFeedback(node.offset, node.length, 'kind', 'oldName');
@@ -676,7 +710,8 @@ class _RefactoringManager {
}
}
- void _reset([engine.AnalysisContext context]) {
+ void _reset() {
+ test_resetCount++;
kind = null;
offset = null;
length = null;
@@ -685,6 +720,28 @@ class _RefactoringManager {
initStatus = new RefactoringStatus();
optionsStatus = new RefactoringStatus();
finalStatus = new RefactoringStatus();
+ subscriptionToReset?.cancel();
+ subscriptionToReset = null;
+ }
+
+ void _resetOnAnalysisStarted() {
+ subscriptionToReset = server.onAnalysisStarted.listen((_) => _reset());
Brian Wilkerson 2016/08/22 23:32:23 Should we assert that `subscriptionToReset` is nul
scheglov 2016/08/23 01:55:28 Well, we need to at least cancel the current subsc
+ }
+
+ /**
+ * We're performing a refactoring that affects only the given [file].
+ * So, when the [file] resolution is changed, we need to reset refactoring.
+ * But when any other file is changed or analyzer, we can continue.
+ */
+ void _resetOnFileResolutionChanged(String file) {
+ engine.AnalysisContext context = server.getAnalysisContext(file);
+ subscriptionToReset =
+ context?.onResultChanged(RESOLVED_UNIT)?.listen((event) {
+ Source targetSource = event.target.source;
+ if (targetSource?.fullName == file) {
+ _reset();
+ }
+ });
}
void _sendResultResponse() {
« no previous file with comments | « no previous file | pkg/analysis_server/test/analysis_abstract.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698