blob: 35826f009e7078b44fcb5d579f46acf14aaff101 [file] [log] [blame]
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import '../../../protocol_server.dart'
show CompletionSuggestion, CompletionSuggestionKind;
/**
* A contributor for calculating prefixed import library member suggestions
* `completion.getSuggestions` request results.
*/
class LibraryMemberContributor extends DartCompletionContributor {
@override
Future<List<CompletionSuggestion>> computeSuggestions(
DartCompletionRequest request) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
// Determine if the target looks like a library prefix
Expression targetId = request.dotTarget;
if (targetId is SimpleIdentifier && !request.target.isCascade) {
Element elem = targetId.staticElement;
if (elem is PrefixElement && !elem.isSynthetic) {
LibraryElement containingLibrary = request.libraryElement;
// Gracefully degrade if the library or directives
// could not be determined (e.g. detached part file or source change)
if (containingLibrary != null) {
List<ImportElement> imports = containingLibrary.imports;
if (imports != null) {
return _buildSuggestions(request, elem, containingLibrary, imports);
}
}
}
}
return const <CompletionSuggestion>[];
}
List<CompletionSuggestion> _buildSuggestions(
DartCompletionRequest request,
PrefixElement elem,
LibraryElement containingLibrary,
List<ImportElement> imports) {
List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
for (ImportElement importElem in imports) {
if (importElem.prefix?.name == elem.name) {
LibraryElement library = importElem.importedLibrary;
if (library != null) {
// Suggest elements from the imported library
AstNode parent = request.target.containingNode.parent;
bool isConstructor = parent.parent is ConstructorName;
bool typesOnly = parent is TypeName;
bool instCreation = typesOnly && isConstructor;
LibraryElementSuggestionBuilder builder =
new LibraryElementSuggestionBuilder(containingLibrary,
CompletionSuggestionKind.INVOCATION, typesOnly, instCreation);
for (var element in importElem.namespace.definedNames.values) {
element.accept(builder);
}
suggestions.addAll(builder.suggestions);
// If the import is 'deferred' then suggest 'loadLibrary'
if (importElem.isDeferred) {
FunctionElement loadLibFunct = library.loadLibraryFunction;
suggestions.add(createSuggestion(loadLibFunct));
}
}
}
}
return suggestions;
}
}