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

Side by Side Diff: pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart

Issue 1520613003: simplify contributors by resolving declarations in scope (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: merge Created 5 years 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
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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.completion.dart.manager; 5 library services.completion.dart.manager;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:analysis_server/plugin/protocol/protocol.dart'; 9 import 'package:analysis_server/plugin/protocol/protocol.dart';
10 import 'package:analysis_server/src/provisional/completion/completion_core.dart' 10 import 'package:analysis_server/src/provisional/completion/completion_core.dart'
(...skipping 13 matching lines...) Expand all
24 import 'package:analyzer/src/task/dart.dart'; 24 import 'package:analyzer/src/task/dart.dart';
25 import 'package:analyzer/task/dart.dart'; 25 import 'package:analyzer/task/dart.dart';
26 26
27 /** 27 /**
28 * [DartCompletionManager] determines if a completion request is Dart specific 28 * [DartCompletionManager] determines if a completion request is Dart specific
29 * and forwards those requests to all [DartCompletionContributor]s. 29 * and forwards those requests to all [DartCompletionContributor]s.
30 */ 30 */
31 class DartCompletionManager implements CompletionContributor { 31 class DartCompletionManager implements CompletionContributor {
32 @override 32 @override
33 Future<List<CompletionSuggestion>> computeSuggestions( 33 Future<List<CompletionSuggestion>> computeSuggestions(
34 CompletionRequest request) { 34 CompletionRequest request) async {
35 if (AnalysisEngine.isDartFileName(request.source.shortName)) { 35 if (!AnalysisEngine.isDartFileName(request.source.shortName)) {
36 return _computeDartSuggestions( 36 return EMPTY_LIST;
37 new DartCompletionRequestImpl.forRequest(request));
38 } 37 }
39 return new Future.value();
40 }
41 38
42 /**
43 * Return a [Future] that completes with a list of suggestions
44 * for the given completion [request].
45 */
46 Future<List<CompletionSuggestion>> _computeDartSuggestions(
47 DartCompletionRequest request) async {
48 // Request Dart specific completions from each contributor 39 // Request Dart specific completions from each contributor
40 DartCompletionRequestImpl dartRequest =
41 await DartCompletionRequestImpl.from(request);
49 List<CompletionSuggestion> suggestions = <CompletionSuggestion>[]; 42 List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
50 for (DartCompletionContributor c in dartCompletionPlugin.contributors) { 43 for (DartCompletionContributor c in dartCompletionPlugin.contributors) {
51 suggestions.addAll(await c.computeSuggestions(request)); 44 suggestions.addAll(await c.computeSuggestions(dartRequest));
52 } 45 }
53 return suggestions; 46 return suggestions;
54 } 47 }
55 } 48 }
56 49
57 /** 50 /**
58 * The information about a requested list of completions within a Dart file. 51 * The information about a requested list of completions within a Dart file.
59 */ 52 */
60 class DartCompletionRequestImpl extends CompletionRequestImpl 53 class DartCompletionRequestImpl extends CompletionRequestImpl
61 implements DartCompletionRequest { 54 implements DartCompletionRequest {
62 /** 55 /**
63 * The source for the library containing the completion request. 56 * Return a [Future] that completes with a newly created completion request
64 * This may be different from the source in which the completion is requested 57 * based on the given [request].
65 * if the completion is being requested in a part file.
66 * This may be `null` if the library for a part file cannot be determined.
67 */ 58 */
68 Source _librarySource; 59 static Future<DartCompletionRequest> from(CompletionRequest request) async {
60 Source source = request.source;
61 AnalysisContext context = request.context;
62 CompilationUnit unit = request.context.computeResult(source, PARSED_UNIT);
63
64 Source libSource;
65 if (unit.directives.any((d) => d is PartOfDirective)) {
66 List<Source> libraries = context.getLibrariesContaining(source);
67 if (libraries.isNotEmpty) {
68 libSource = libraries[0];
69 }
70 } else {
71 libSource = source;
72 }
73
74 // Most (all?) contributors need declarations in scope to be resolved
75 if (libSource != null) {
76 unit = await new AnalysisFutureHelper<CompilationUnit>(context,
77 new LibrarySpecificUnit(libSource, source), RESOLVED_UNIT3)
78 .computeAsync();
79 }
80
81 return new DartCompletionRequestImpl._(
82 request.context,
83 request.resourceProvider,
84 request.searchEngine,
85 libSource,
86 request.source,
87 request.offset,
88 unit);
89 }
90
91 DartCompletionRequestImpl._(
92 AnalysisContext context,
93 ResourceProvider resourceProvider,
94 SearchEngine searchEngine,
95 this.librarySource,
96 Source source,
97 int offset,
98 CompilationUnit unit)
99 : super(context, resourceProvider, searchEngine, source, offset) {
100 _updateTargets(unit);
101 }
69 102
70 /** 103 /**
71 * The [DartType] for Object in dart:core 104 * The [DartType] for Object in dart:core
72 */ 105 */
73 InterfaceType _objectType; 106 InterfaceType _objectType;
74 107
75 /**
76 * `true` if [resolveDeclarationsInScope] has partially resolved the unit
77 * referenced by [target], else `false`.
78 */
79 bool _haveResolveDeclarationsInScope = false;
80
81 @override 108 @override
82 Expression dotTarget; 109 Expression dotTarget;
83 110
84 @override 111 @override
112 Source librarySource;
113
114 @override
85 CompletionTarget target; 115 CompletionTarget target;
86 116
87 /**
88 * Initialize a newly created completion request based on the given request.
89 */
90 factory DartCompletionRequestImpl.forRequest(CompletionRequest request) {
91 return new DartCompletionRequestImpl._(
92 request.context,
93 request.resourceProvider,
94 request.searchEngine,
95 request.source,
96 request.offset);
97 }
98
99 DartCompletionRequestImpl._(
100 AnalysisContext context,
101 ResourceProvider resourceProvider,
102 SearchEngine searchEngine,
103 Source source,
104 int offset)
105 : super(context, resourceProvider, searchEngine, source, offset) {
106 _updateTargets(context.computeResult(source, PARSED_UNIT));
107 if (target.unit.directives.any((d) => d is PartOfDirective)) {
108 List<Source> libraries = context.getLibrariesContaining(source);
109 if (libraries.isNotEmpty) {
110 _librarySource = libraries[0];
111 }
112 } else {
113 _librarySource = source;
114 }
115 }
116
117 @override 117 @override
118 Future<LibraryElement> get libraryElement async { 118 Future<LibraryElement> get libraryElement async {
119 //TODO(danrubel) build the library element rather than all the declarations 119 //TODO(danrubel) build the library element rather than all the declarations
120 CompilationUnit unit = await resolveDeclarationsInScope(); 120 CompilationUnit unit = target.unit;
121 if (unit != null) { 121 if (unit != null) {
122 CompilationUnitElement elem = unit.element; 122 CompilationUnitElement elem = unit.element;
123 if (elem != null) { 123 if (elem != null) {
124 return elem.library; 124 return elem.library;
125 } 125 }
126 } 126 }
127 return null; 127 return null;
128 } 128 }
129 129
130 @override 130 @override
131 InterfaceType get objectType { 131 InterfaceType get objectType {
132 if (_objectType == null) { 132 if (_objectType == null) {
133 Source coreUri = context.sourceFactory.forUri('dart:core'); 133 Source coreUri = context.sourceFactory.forUri('dart:core');
134 LibraryElement coreLib = context.getLibraryElement(coreUri); 134 LibraryElement coreLib = context.getLibraryElement(coreUri);
135 _objectType = coreLib.getType('Object').type; 135 _objectType = coreLib.getType('Object').type;
136 } 136 }
137 return _objectType; 137 return _objectType;
138 } 138 }
139 139
140 @override 140 @override
141 Future<CompilationUnit> resolveDeclarationsInScope() async {
142 CompilationUnit unit = target.unit;
143 if (_haveResolveDeclarationsInScope) {
144 return unit;
145 }
146
147 // Gracefully degrade if librarySource cannot be determined
148 if (_librarySource == null) {
149 return null;
150 }
151
152 // Resolve declarations in the target unit
153 CompilationUnit resolvedUnit =
154 await new AnalysisFutureHelper<CompilationUnit>(context,
155 new LibrarySpecificUnit(_librarySource, source), RESOLVED_UNIT3)
156 .computeAsync();
157
158 // TODO(danrubel) determine if the underlying source has been modified
159 // in a way that invalidates the completion request
160 // and return null
161
162 // Gracefully degrade if unit cannot be resolved
163 if (resolvedUnit == null) {
164 return null;
165 }
166
167 // Recompute the target for the newly resolved unit
168 _updateTargets(resolvedUnit);
169 _haveResolveDeclarationsInScope = true;
170 return resolvedUnit;
171 }
172
173 @override
174 Future<List<Directive>> resolveDirectives() async { 141 Future<List<Directive>> resolveDirectives() async {
175 CompilationUnit libUnit; 142 CompilationUnit libUnit;
176 if (_librarySource == source) { 143 if (librarySource == source) {
177 libUnit = await resolveDeclarationsInScope(); 144 libUnit = target.unit;
178 } else if (_librarySource != null) { 145 } else if (librarySource != null) {
146 // TODO(danrubel) only resolve the directives
179 libUnit = await new AnalysisFutureHelper<CompilationUnit>( 147 libUnit = await new AnalysisFutureHelper<CompilationUnit>(
180 context, 148 context,
181 new LibrarySpecificUnit(_librarySource, _librarySource), 149 new LibrarySpecificUnit(librarySource, librarySource),
182 RESOLVED_UNIT3) 150 RESOLVED_UNIT3)
183 .computeAsync(); 151 .computeAsync();
184 } 152 }
185 return libUnit?.directives; 153 return libUnit?.directives;
186 } 154 }
187 155
188 @override 156 @override
189 Future resolveExpression(Expression expression) async { 157 Future resolveExpression(Expression expression) async {
190 //TODO(danrubel) resolve the expression or containing method 158 // Return immediately if the expression has already been resolved
191 // rather than the entire complilation unit 159 if (expression.propagatedType != null) {
160 return;
161 }
192 162
193 // Gracefully degrade if librarySource cannot be determined 163 // Gracefully degrade if librarySource cannot be determined
194 if (_librarySource == null) { 164 if (librarySource == null) {
195 return null; 165 return;
196 } 166 }
197 167
198 // Resolve declarations in the target unit 168 // Resolve declarations in the target unit
169 // TODO(danrubel) resolve the expression or containing method
170 // rather than the entire complilation unit
199 CompilationUnit resolvedUnit = 171 CompilationUnit resolvedUnit =
200 await new AnalysisFutureHelper<CompilationUnit>(context, 172 await new AnalysisFutureHelper<CompilationUnit>(context,
201 new LibrarySpecificUnit(_librarySource, source), RESOLVED_UNIT) 173 new LibrarySpecificUnit(librarySource, source), RESOLVED_UNIT)
202 .computeAsync(); 174 .computeAsync();
203 175
204 // TODO(danrubel) determine if the underlying source has been modified 176 // TODO(danrubel) determine if the underlying source has been modified
205 // in a way that invalidates the completion request 177 // in a way that invalidates the completion request
206 // and return null 178 // and return null
207 179
208 // Gracefully degrade if unit cannot be resolved 180 // Gracefully degrade if unit cannot be resolved
209 if (resolvedUnit == null) { 181 if (resolvedUnit == null) {
210 return null; 182 return;
211 } 183 }
212 184
213 // Recompute the target for the newly resolved unit 185 // Recompute the target for the newly resolved unit
214 _updateTargets(resolvedUnit); 186 _updateTargets(resolvedUnit);
215 _haveResolveDeclarationsInScope = true;
216 } 187 }
217 188
218 /** 189 /**
219 * Update the completion [target] and [dotTarget] based on the given [unit]. 190 * Update the completion [target] and [dotTarget] based on the given [unit].
220 */ 191 */
221 void _updateTargets(CompilationUnit unit) { 192 void _updateTargets(CompilationUnit unit) {
222 dotTarget = null; 193 dotTarget = null;
223 target = new CompletionTarget.forOffset(unit, offset); 194 target = new CompletionTarget.forOffset(unit, offset);
224 AstNode node = target.containingNode; 195 AstNode node = target.containingNode;
225 if (node is MethodInvocation) { 196 if (node is MethodInvocation) {
(...skipping 10 matching lines...) Expand all
236 dotTarget = node.realTarget; 207 dotTarget = node.realTarget;
237 } 208 }
238 } 209 }
239 if (node is PrefixedIdentifier) { 210 if (node is PrefixedIdentifier) {
240 if (identical(node.identifier, target.entity)) { 211 if (identical(node.identifier, target.entity)) {
241 dotTarget = node.prefix; 212 dotTarget = node.prefix;
242 } 213 }
243 } 214 }
244 } 215 }
245 } 216 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698