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

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

Issue 1470863003: Rework contribution sorter to use futures (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: merge Created 5 years, 1 month 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library services.completion.computer.dart.relevance;
6
7 import 'package:analysis_server/src/protocol_server.dart' as protocol;
8 import 'package:analysis_server/src/protocol_server.dart'
9 show CompletionSuggestion, CompletionSuggestionKind;
10 import 'package:analysis_server/src/provisional/completion/completion_core.dart' ;
11 import 'package:analysis_server/src/provisional/completion/dart/completion_targe t.dart';
12 import 'package:analysis_server/src/services/completion/contribution_sorter.dart ';
13 import 'package:analysis_server/src/services/completion/dart_completion_manager. dart'
14 show DART_RELEVANCE_COMMON_USAGE;
15 import 'package:analyzer/src/generated/ast.dart';
16 import 'package:analyzer/src/generated/element.dart';
17 import 'package:analyzer/src/task/dart.dart';
18 import 'package:analyzer/task/dart.dart';
19
20 part 'common_usage_generated.dart';
21
22 /**
23 * A computer for adjusting the relevance of completions computed by others
24 * based upon common Dart usage patterns. This is a long-lived object
25 * that should not maintain state between calls to it's [sort] method.
26 */
27 class CommonUsageComputer implements ContributionSorter {
28 /**
29 * A map of <library>.<classname> to an ordered list of method names,
30 * field names, getter names, and named constructors.
31 * The names are ordered from most relevant to least relevant.
32 * Names not listed are considered equally less relevant than those listed.
33 */
34 Map<String, List<String>> selectorRelevance;
35
36 CommonUsageComputer([this.selectorRelevance = defaultSelectorRelevance]);
37
38 @override
39 AnalysisRequest sort(CompletionRequest request,
40 Iterable<CompletionSuggestion> suggestions) {
41 _update(request, suggestions);
42 return null;
43 }
44
45 CompletionTarget _getCompletionTarget(CompletionRequest request) {
46 // TODO (danrubel) get cached completion target
47 var libSrcs = request.context.getLibrariesContaining(request.source);
48 if (libSrcs.length == 0) {
49 return null;
50 }
51 var libElem = request.context.getResult(libSrcs[0], LIBRARY_ELEMENT1);
52 if (libElem is LibraryElement) {
53 var unit = request.context.getResult(
54 new LibrarySpecificUnit(libElem.source, request.source),
55 RESOLVED_UNIT3);
56 if (unit is CompilationUnit) {
57 return new CompletionTarget.forOffset(unit, request.offset);
58 }
59 }
60 return null;
61 }
62
63 /**
64 * Adjusts the relevance based on the given completion context.
65 * The compilation unit and completion node
66 * in the given completion context may not be resolved.
67 */
68 void _update(
69 CompletionRequest request, Iterable<CompletionSuggestion> suggestions) {
70 var target = _getCompletionTarget(request);
71 if (target != null) {
72 var visitor = new _BestTypeVisitor(target.entity);
73 DartType type = target.containingNode.accept(visitor);
74 if (type != null) {
75 Element typeElem = type.element;
76 if (typeElem != null) {
77 LibraryElement libElem = typeElem.library;
78 if (libElem != null) {
79 _updateInvocationRelevance(type, libElem, suggestions);
80 }
81 }
82 }
83 }
84 }
85
86 /**
87 * Adjusts the relevance of all method suggestions based upon the given
88 * target type and library.
89 */
90 void _updateInvocationRelevance(DartType type, LibraryElement libElem,
91 Iterable<CompletionSuggestion> suggestions) {
92 String typeName = type.name;
93 List<String> selectors = selectorRelevance['${libElem.name}.${typeName}'];
94 if (selectors != null) {
95 for (CompletionSuggestion suggestion in suggestions) {
96 protocol.Element element = suggestion.element;
97 if (element != null &&
98 (element.kind == protocol.ElementKind.CONSTRUCTOR ||
99 element.kind == protocol.ElementKind.FIELD ||
100 element.kind == protocol.ElementKind.GETTER ||
101 element.kind == protocol.ElementKind.METHOD ||
102 element.kind == protocol.ElementKind.SETTER) &&
103 suggestion.kind == CompletionSuggestionKind.INVOCATION &&
104 suggestion.declaringType == typeName) {
105 int index = selectors.indexOf(suggestion.completion);
106 if (index != -1) {
107 suggestion.relevance = DART_RELEVANCE_COMMON_USAGE - index;
108 }
109 }
110 }
111 }
112 }
113 }
114
115 /**
116 * An [AstVisitor] used to determine the best defining type of a node.
117 */
118 class _BestTypeVisitor extends GeneralizingAstVisitor {
119 /**
120 * The entity which the completed text will replace (or which will be
121 * displaced once the completed text is inserted). This may be an AstNode or
122 * a Token, or it may be null if the cursor is after all tokens in the file.
123 * See field of the same name in [CompletionTarget].
124 */
125 final Object entity;
126
127 _BestTypeVisitor(this.entity);
128
129 DartType visitConstructorName(ConstructorName node) {
130 if (node.period != null && node.name == entity) {
131 TypeName typeName = node.type;
132 if (typeName != null) {
133 return typeName.type;
134 }
135 }
136 return null;
137 }
138
139 DartType visitNode(AstNode node) {
140 return null;
141 }
142
143 DartType visitPrefixedIdentifier(PrefixedIdentifier node) {
144 if (node.identifier == entity) {
145 SimpleIdentifier prefix = node.prefix;
146 if (prefix != null) {
147 return prefix.bestType;
148 }
149 }
150 return null;
151 }
152
153 DartType visitPropertyAccess(PropertyAccess node) {
154 if (node.propertyName == entity) {
155 Expression target = node.realTarget;
156 if (target != null) {
157 return target.bestType;
158 }
159 }
160 return null;
161 }
162 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698