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

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

Issue 925723002: update code completion suggestion relevance based on common usage (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: add support for field/getter/setter relevance Created 5 years, 10 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 unified diff | Download patch | Annotate | Revision Log
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' show
9 CompletionSuggestion, CompletionSuggestionKind;
10 import 'package:analysis_server/src/services/completion/dart_completion_manager. dart';
11 import 'package:analyzer/src/generated/ast.dart';
12 import 'package:analyzer/src/generated/element.dart';
13
14 /**
15 * A map of <library>.<classname> to an ordered list of method names,
16 * field names, getter names, and named constructors.
17 * The names are ordered from most relevant to least relevant.
18 * Names not listed are considered equally less relevant than those listed.
19 */
20 const Map<String, List<String>> defaultSelectorRelevance = const {//
21 // Sample implementation which updates the relevance of the following
22 // new Random().nextInt(...)
23 // new Random().nextDouble(...)
24 // new Random().nextBool() - not commonly used thus omitted from list
25 // Entries should look something like this
26 // 'dart.math.Random': const ['nextInt', 'nextDouble'],
27 // 'dart.async.Future': const ['value', 'wait'],
28 };
29
30 /**
31 * A computer for adjusting the relevance of completions computed by others
32 * based upon common Dart usage patterns.
33 */
34 class CommonUsageComputer {
35 /**
36 * A map of <library>.<classname> to an ordered list of method names,
37 * field names, getter names, and named constructors.
38 * The names are ordered from most relevant to least relevant.
39 * Names not listed are considered equally less relevant than those listed.
40 */
41 Map<String, List<String>> selectorRelevance;
42
43 CommonUsageComputer([this.selectorRelevance = defaultSelectorRelevance]);
44
45 /**
46 * Adjusts the relevance based on the given completion context.
47 * The compilation unit and completion node
48 * in the given completion context may not be resolved.
49 * This method should execute quickly and not block waiting for any analysis.
50 */
51 void computeFast(DartCompletionRequest request) {
52 _update(request);
53 }
54
55 /**
56 * Adjusts the relevance based on the given completion context.
57 * The compilation unit and completion node
58 * in the given completion context are resolved.
59 */
60 void computeFull(DartCompletionRequest request) {
61 _update(request);
62 }
63
64 /**
65 * Adjusts the relevance based on the given completion context.
66 * The compilation unit and completion node
67 * in the given completion context may not be resolved.
68 */
69 void _update(DartCompletionRequest request) {
70 var visitor = new _BestTypeVisitor(request.target.entity);
71 DartType type = request.target.containingNode.accept(visitor);
72 if (type != null) {
73 Element typeElem = type.element;
74 if (typeElem != null) {
75 LibraryElement libElem = typeElem.library;
76 if (libElem != null) {
77 _updateInvocationRelevance(request, type, libElem);
78 }
79 }
80 }
81 }
82
83 /**
84 * Adjusts the relevance of all method suggestions based upon the given
85 * target type and library.
86 */
87 void _updateInvocationRelevance(DartCompletionRequest request, DartType type,
88 LibraryElement libElem) {
89 String typeName = type.name;
90 List<String> selectors = selectorRelevance['${libElem.name}.${typeName}'];
91 if (selectors != null) {
92 for (CompletionSuggestion suggestion in request.suggestions) {
93 protocol.Element element = suggestion.element;
94 if (element != null &&
95 (element.kind == protocol.ElementKind.CONSTRUCTOR ||
96 element.kind == protocol.ElementKind.FIELD ||
97 element.kind == protocol.ElementKind.GETTER ||
98 element.kind == protocol.ElementKind.METHOD ||
99 element.kind == protocol.ElementKind.SETTER) &&
100 suggestion.kind == CompletionSuggestionKind.INVOCATION &&
101 suggestion.declaringType == typeName) {
102 int index = selectors.indexOf(suggestion.completion);
103 if (index != -1) {
104 suggestion.relevance = DART_RELEVANCE_COMMON_USAGE - index;
105 }
106 }
107 }
108 }
109 }
110 }
111
112 /**
113 * An [AstVisitor] used to determine the best defining type of a node.
114 */
115 class _BestTypeVisitor extends GeneralizingAstVisitor {
116
117 /**
118 * The entity which the completed text will replace (or which will be
119 * displaced once the completed text is inserted). This may be an AstNode or
120 * a Token, or it may be null if the cursor is after all tokens in the file.
121 * See field of the same name in [CompletionTarget].
122 */
123 final Object entity;
124
125 _BestTypeVisitor(this.entity);
126
127 DartType visitConstructorName(ConstructorName node) {
128 if (node.period != null && node.name == entity) {
129 TypeName typeName = node.type;
130 if (typeName != null) {
131 return typeName.type;
132 }
133 }
134 return null;
135 }
136
137 DartType visitNode(AstNode node) {
138 return null;
139 }
140
141 DartType visitPrefixedIdentifier(PrefixedIdentifier node) {
142 if (node.identifier == entity) {
143 SimpleIdentifier prefix = node.prefix;
144 if (prefix != null) {
145 return prefix.bestType;
146 }
147 }
148 return null;
149 }
150
151 DartType visitPropertyAccess(PropertyAccess node) {
152 if (node.propertyName == entity) {
153 Expression target = node.realTarget;
154 if (target != null) {
155 return target.bestType;
156 }
157 }
158 return null;
159 }
160 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698