| OLD | NEW |
| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 implements DartCompletionRequest { | 61 implements DartCompletionRequest { |
| 62 /** | 62 /** |
| 63 * The source for the library containing the completion request. | 63 * The source for the library containing the completion request. |
| 64 * This may be different from the source in which the completion is requested | 64 * This may be different from the source in which the completion is requested |
| 65 * if the completion is being requested in a part file. | 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. | 66 * This may be `null` if the library for a part file cannot be determined. |
| 67 */ | 67 */ |
| 68 Source _librarySource; | 68 Source _librarySource; |
| 69 | 69 |
| 70 /** | 70 /** |
| 71 * The cached completion target or `null` if not computed yet. | |
| 72 */ | |
| 73 CompletionTarget _target; | |
| 74 | |
| 75 /** | |
| 76 * The [DartType] for Object in dart:core | 71 * The [DartType] for Object in dart:core |
| 77 */ | 72 */ |
| 78 InterfaceType _objectType; | 73 InterfaceType _objectType; |
| 79 | 74 |
| 80 /** | 75 /** |
| 81 * `true` if [resolveDeclarationsInScope] has partially resolved the unit | 76 * `true` if [resolveDeclarationsInScope] has partially resolved the unit |
| 82 * referenced by [target], else `false`. | 77 * referenced by [target], else `false`. |
| 83 */ | 78 */ |
| 84 bool _haveResolveDeclarationsInScope = false; | 79 bool _haveResolveDeclarationsInScope = false; |
| 85 | 80 |
| 81 @override |
| 82 Expression dotTarget; |
| 83 |
| 84 @override |
| 85 CompletionTarget target; |
| 86 |
| 86 /** | 87 /** |
| 87 * Initialize a newly created completion request based on the given request. | 88 * Initialize a newly created completion request based on the given request. |
| 88 */ | 89 */ |
| 89 factory DartCompletionRequestImpl.forRequest(CompletionRequest request) { | 90 factory DartCompletionRequestImpl.forRequest(CompletionRequest request) { |
| 90 return new DartCompletionRequestImpl._( | 91 return new DartCompletionRequestImpl._( |
| 91 request.context, | 92 request.context, |
| 92 request.resourceProvider, | 93 request.resourceProvider, |
| 93 request.searchEngine, | 94 request.searchEngine, |
| 94 request.source, | 95 request.source, |
| 95 request.offset); | 96 request.offset); |
| 96 } | 97 } |
| 97 | 98 |
| 98 DartCompletionRequestImpl._( | 99 DartCompletionRequestImpl._( |
| 99 AnalysisContext context, | 100 AnalysisContext context, |
| 100 ResourceProvider resourceProvider, | 101 ResourceProvider resourceProvider, |
| 101 SearchEngine searchEngine, | 102 SearchEngine searchEngine, |
| 102 Source source, | 103 Source source, |
| 103 int offset) | 104 int offset) |
| 104 : super(context, resourceProvider, searchEngine, source, offset) { | 105 : super(context, resourceProvider, searchEngine, source, offset) { |
| 106 _updateTargets(context.computeResult(source, PARSED_UNIT)); |
| 105 if (target.unit.directives.any((d) => d is PartOfDirective)) { | 107 if (target.unit.directives.any((d) => d is PartOfDirective)) { |
| 106 List<Source> libraries = context.getLibrariesContaining(source); | 108 List<Source> libraries = context.getLibrariesContaining(source); |
| 107 if (libraries.isNotEmpty) { | 109 if (libraries.isNotEmpty) { |
| 108 _librarySource = libraries[0]; | 110 _librarySource = libraries[0]; |
| 109 } | 111 } |
| 110 } else { | 112 } else { |
| 111 _librarySource = source; | 113 _librarySource = source; |
| 112 } | 114 } |
| 113 } | 115 } |
| 114 | 116 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 129 InterfaceType get objectType { | 131 InterfaceType get objectType { |
| 130 if (_objectType == null) { | 132 if (_objectType == null) { |
| 131 Source coreUri = context.sourceFactory.forUri('dart:core'); | 133 Source coreUri = context.sourceFactory.forUri('dart:core'); |
| 132 LibraryElement coreLib = context.getLibraryElement(coreUri); | 134 LibraryElement coreLib = context.getLibraryElement(coreUri); |
| 133 _objectType = coreLib.getType('Object').type; | 135 _objectType = coreLib.getType('Object').type; |
| 134 } | 136 } |
| 135 return _objectType; | 137 return _objectType; |
| 136 } | 138 } |
| 137 | 139 |
| 138 @override | 140 @override |
| 139 CompletionTarget get target { | |
| 140 if (_target == null) { | |
| 141 CompilationUnit unit = context.computeResult(source, PARSED_UNIT); | |
| 142 _target = new CompletionTarget.forOffset(unit, offset); | |
| 143 } | |
| 144 return _target; | |
| 145 } | |
| 146 | |
| 147 @override | |
| 148 Future<CompilationUnit> resolveDeclarationsInScope() async { | 141 Future<CompilationUnit> resolveDeclarationsInScope() async { |
| 149 CompilationUnit unit = target.unit; | 142 CompilationUnit unit = target.unit; |
| 150 if (_haveResolveDeclarationsInScope) { | 143 if (_haveResolveDeclarationsInScope) { |
| 151 return unit; | 144 return unit; |
| 152 } | 145 } |
| 153 | 146 |
| 154 // Gracefully degrade if librarySource cannot be determined | 147 // Gracefully degrade if librarySource cannot be determined |
| 155 if (_librarySource == null) { | 148 if (_librarySource == null) { |
| 156 return null; | 149 return null; |
| 157 } | 150 } |
| 158 | 151 |
| 159 // Resolve declarations in the target unit | 152 // Resolve declarations in the target unit |
| 160 CompilationUnit resolvedUnit = | 153 CompilationUnit resolvedUnit = |
| 161 await new AnalysisFutureHelper<CompilationUnit>(context, | 154 await new AnalysisFutureHelper<CompilationUnit>(context, |
| 162 new LibrarySpecificUnit(_librarySource, source), RESOLVED_UNIT3) | 155 new LibrarySpecificUnit(_librarySource, source), RESOLVED_UNIT3) |
| 163 .computeAsync(); | 156 .computeAsync(); |
| 164 | 157 |
| 165 // TODO(danrubel) determine if the underlying source has been modified | 158 // TODO(danrubel) determine if the underlying source has been modified |
| 166 // in a way that invalidates the completion request | 159 // in a way that invalidates the completion request |
| 167 // and return null | 160 // and return null |
| 168 | 161 |
| 169 // Gracefully degrade if unit cannot be resolved | 162 // Gracefully degrade if unit cannot be resolved |
| 170 if (resolvedUnit == null) { | 163 if (resolvedUnit == null) { |
| 171 return null; | 164 return null; |
| 172 } | 165 } |
| 173 | 166 |
| 174 // Recompute the target for the newly resolved unit | 167 // Recompute the target for the newly resolved unit |
| 175 _target = new CompletionTarget.forOffset(resolvedUnit, offset); | 168 _updateTargets(resolvedUnit); |
| 176 _haveResolveDeclarationsInScope = true; | 169 _haveResolveDeclarationsInScope = true; |
| 177 return resolvedUnit; | 170 return resolvedUnit; |
| 178 } | 171 } |
| 179 | 172 |
| 180 @override | 173 @override |
| 181 Future<List<Directive>> resolveDirectives() async { | 174 Future<List<Directive>> resolveDirectives() async { |
| 182 CompilationUnit libUnit; | 175 CompilationUnit libUnit; |
| 183 if (_librarySource == source) { | 176 if (_librarySource == source) { |
| 184 libUnit = await resolveDeclarationsInScope(); | 177 libUnit = await resolveDeclarationsInScope(); |
| 185 } else if (_librarySource != null) { | 178 } else if (_librarySource != null) { |
| 186 libUnit = | 179 libUnit = await new AnalysisFutureHelper<CompilationUnit>( |
| 187 await new AnalysisFutureHelper<CompilationUnit>( | 180 context, |
| 188 context, | 181 new LibrarySpecificUnit(_librarySource, _librarySource), |
| 189 new LibrarySpecificUnit(_librarySource, _librarySource), | 182 RESOLVED_UNIT3) |
| 190 RESOLVED_UNIT3) | 183 .computeAsync(); |
| 191 .computeAsync(); | |
| 192 } | 184 } |
| 193 return libUnit?.directives; | 185 return libUnit?.directives; |
| 194 } | 186 } |
| 195 | 187 |
| 196 @override | 188 @override |
| 197 Future resolveExpression(Expression expression) async { | 189 Future resolveExpression(Expression expression) async { |
| 198 //TODO(danrubel) resolve the expression or containing method | 190 //TODO(danrubel) resolve the expression or containing method |
| 199 // rather than the entire complilation unit | 191 // rather than the entire complilation unit |
| 200 | 192 |
| 201 // Gracefully degrade if librarySource cannot be determined | 193 // Gracefully degrade if librarySource cannot be determined |
| (...skipping 10 matching lines...) Expand all Loading... |
| 212 // TODO(danrubel) determine if the underlying source has been modified | 204 // TODO(danrubel) determine if the underlying source has been modified |
| 213 // in a way that invalidates the completion request | 205 // in a way that invalidates the completion request |
| 214 // and return null | 206 // and return null |
| 215 | 207 |
| 216 // Gracefully degrade if unit cannot be resolved | 208 // Gracefully degrade if unit cannot be resolved |
| 217 if (resolvedUnit == null) { | 209 if (resolvedUnit == null) { |
| 218 return null; | 210 return null; |
| 219 } | 211 } |
| 220 | 212 |
| 221 // Recompute the target for the newly resolved unit | 213 // Recompute the target for the newly resolved unit |
| 222 _target = new CompletionTarget.forOffset(resolvedUnit, offset); | 214 _updateTargets(resolvedUnit); |
| 223 _haveResolveDeclarationsInScope = true; | 215 _haveResolveDeclarationsInScope = true; |
| 224 } | 216 } |
| 217 |
| 218 /** |
| 219 * Update the completion [target] and [dotTarget] based on the given [unit]. |
| 220 */ |
| 221 void _updateTargets(CompilationUnit unit) { |
| 222 dotTarget = null; |
| 223 target = new CompletionTarget.forOffset(unit, offset); |
| 224 AstNode node = target.containingNode; |
| 225 if (node is MethodInvocation) { |
| 226 if (identical(node.methodName, target.entity)) { |
| 227 dotTarget = node.realTarget; |
| 228 } else if (node.isCascaded && node.operator.offset + 1 == target.offset) { |
| 229 dotTarget = node.realTarget; |
| 230 } |
| 231 } |
| 232 if (node is PropertyAccess) { |
| 233 if (identical(node.propertyName, target.entity)) { |
| 234 dotTarget = node.realTarget; |
| 235 } else if (node.isCascaded && node.operator.offset + 1 == target.offset) { |
| 236 dotTarget = node.realTarget; |
| 237 } |
| 238 } |
| 239 if (node is PrefixedIdentifier) { |
| 240 if (identical(node.identifier, target.entity)) { |
| 241 dotTarget = node.prefix; |
| 242 } |
| 243 } |
| 244 } |
| 225 } | 245 } |
| OLD | NEW |