Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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.computer.dart.toplevel; | 5 library services.completion.computer.dart.toplevel; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import 'package:analysis_server/src/protocol_server.dart' hide Element, | 10 import 'package:analysis_server/src/protocol_server.dart' hide Element, |
| 11 ElementKind; | 11 ElementKind; |
| 12 import 'package:analysis_server/src/services/completion/dart_completion_cache.da rt'; | 12 import 'package:analysis_server/src/services/completion/dart_completion_cache.da rt'; |
| 13 import 'package:analysis_server/src/services/completion/dart_completion_manager. dart'; | 13 import 'package:analysis_server/src/services/completion/dart_completion_manager. dart'; |
| 14 import 'package:analysis_server/src/services/completion/optype_ast_visitor.dart' ; | |
| 14 import 'package:analysis_server/src/services/completion/suggestion_builder.dart' ; | 15 import 'package:analysis_server/src/services/completion/suggestion_builder.dart' ; |
| 15 import 'package:analyzer/src/generated/ast.dart'; | 16 import 'package:analyzer/src/generated/ast.dart'; |
| 16 import 'package:analyzer/src/generated/element.dart'; | 17 import 'package:analyzer/src/generated/element.dart'; |
| 17 import 'package:analyzer/src/generated/scanner.dart'; | |
| 18 | 18 |
| 19 /** | 19 /** |
| 20 * A computer for calculating imported class and top level variable | 20 * A computer for calculating imported class and top level variable |
| 21 * `completion.getSuggestions` request results. | 21 * `completion.getSuggestions` request results. |
| 22 */ | 22 */ |
| 23 class ImportedComputer extends DartCompletionComputer { | 23 class ImportedComputer extends DartCompletionComputer { |
| 24 bool shouldWaitForLowPrioritySuggestions; | 24 bool shouldWaitForLowPrioritySuggestions; |
| 25 _ImportedSuggestionBuilder builder; | 25 _ImportedSuggestionBuilder builder; |
| 26 | 26 |
| 27 ImportedComputer({this.shouldWaitForLowPrioritySuggestions: false}); | 27 ImportedComputer({this.shouldWaitForLowPrioritySuggestions: false}); |
| 28 | 28 |
| 29 @override | 29 @override |
| 30 bool computeFast(DartCompletionRequest request) { | 30 bool computeFast(DartCompletionRequest request) { |
| 31 builder = request.node.accept(new _ImportedAstVisitor(request)); | 31 |
| 32 if (builder != null) { | 32 // Determine the type of suggestions to be made |
| 33 OpTypeAstVisitor opTypeVisitor = new OpTypeAstVisitor(request.offset); | |
|
Paul Berry
2014/12/16 16:21:56
It looks like many of the computers now invoke OpT
danrubel
2014/12/16 16:51:07
Agreed. This CL got too involved so I pushed that
danrubel
2014/12/16 21:23:18
https://codereview.chromium.org/807743003/
| |
| 34 request.node.accept(opTypeVisitor); | |
| 35 | |
| 36 // Build the suggestions | |
| 37 if (opTypeVisitor.includeTopLevelSuggestions) { | |
| 38 builder = new _ImportedSuggestionBuilder( | |
| 39 request, | |
| 40 typesOnly: opTypeVisitor.includeOnlyTypeNameSuggestions, | |
| 41 excludeVoidReturn: !opTypeVisitor.includeVoidReturnSuggestions); | |
| 33 builder.shouldWaitForLowPrioritySuggestions = | 42 builder.shouldWaitForLowPrioritySuggestions = |
| 34 shouldWaitForLowPrioritySuggestions; | 43 shouldWaitForLowPrioritySuggestions; |
| 35 return builder.computeFast(request.node); | 44 return builder.computeFast(request.node); |
| 36 } | 45 } |
| 37 return true; | 46 return true; |
| 38 } | 47 } |
| 39 | 48 |
| 40 @override | 49 @override |
| 41 Future<bool> computeFull(DartCompletionRequest request) { | 50 Future<bool> computeFull(DartCompletionRequest request) { |
| 42 if (builder != null) { | 51 if (builder != null) { |
| 43 return builder.computeFull(request.node); | 52 return builder.computeFull(request.node); |
| 44 } | 53 } |
| 45 return new Future.value(false); | 54 return new Future.value(false); |
| 46 } | 55 } |
| 47 } | 56 } |
| 48 | 57 |
| 49 /** | 58 /** |
| 50 * [_ImportedAstVisitor] determines whether an import suggestions are needed | |
| 51 * and instantiates the builder to create those suggestions. | |
| 52 */ | |
| 53 class _ImportedAstVisitor extends | |
| 54 GeneralizingAstVisitor<_ImportedSuggestionBuilder> { | |
| 55 final DartCompletionRequest request; | |
| 56 | |
| 57 _ImportedAstVisitor(this.request); | |
| 58 | |
| 59 @override | |
| 60 _ImportedSuggestionBuilder visitArgumentList(ArgumentList node) { | |
| 61 return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true); | |
| 62 } | |
| 63 | |
| 64 @override | |
| 65 _ImportedSuggestionBuilder visitBlock(Block node) { | |
| 66 return new _ImportedSuggestionBuilder(request); | |
| 67 } | |
| 68 | |
| 69 @override | |
| 70 _ImportedSuggestionBuilder visitCascadeExpression(CascadeExpression node) { | |
| 71 // Make suggestions for the target, but not for the selector | |
| 72 // InvocationComputer makes selector suggestions | |
| 73 Expression target = node.target; | |
| 74 if (target != null && request.offset <= target.end) { | |
| 75 return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true); | |
| 76 } | |
| 77 return null; | |
| 78 } | |
| 79 | |
| 80 @override | |
| 81 _ImportedSuggestionBuilder visitClassDeclaration(ClassDeclaration node) { | |
| 82 // Make suggestions in the body of the class declaration | |
| 83 Token leftBracket = node.leftBracket; | |
| 84 if (leftBracket != null && request.offset >= leftBracket.end) { | |
| 85 return new _ImportedSuggestionBuilder(request); | |
| 86 } | |
| 87 return null; | |
| 88 } | |
| 89 | |
| 90 @override | |
| 91 _ImportedSuggestionBuilder visitExpression(Expression node) { | |
| 92 return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true); | |
| 93 } | |
| 94 | |
| 95 @override | |
| 96 _ImportedSuggestionBuilder | |
| 97 visitExpressionStatement(ExpressionStatement node) { | |
| 98 Expression expression = node.expression; | |
| 99 // A pre-variable declaration (e.g. C ^) is parsed as an expression | |
| 100 // statement. Do not make suggestions for the variable name. | |
| 101 if (expression is SimpleIdentifier && request.offset <= expression.end) { | |
| 102 return new _ImportedSuggestionBuilder(request); | |
| 103 } | |
| 104 return null; | |
| 105 } | |
| 106 | |
| 107 @override | |
| 108 _ImportedSuggestionBuilder | |
| 109 visitFormalParameterList(FormalParameterList node) { | |
| 110 Token leftParen = node.leftParenthesis; | |
| 111 if (leftParen != null && request.offset > leftParen.offset) { | |
| 112 Token rightParen = node.rightParenthesis; | |
| 113 if (rightParen == null || request.offset <= rightParen.offset) { | |
| 114 return new _ImportedSuggestionBuilder(request); | |
| 115 } | |
| 116 } | |
| 117 return null; | |
| 118 } | |
| 119 | |
| 120 @override | |
| 121 _ImportedSuggestionBuilder visitForStatement(ForStatement node) { | |
| 122 Token leftParen = node.leftParenthesis; | |
| 123 if (leftParen != null && request.offset >= leftParen.end) { | |
| 124 return new _ImportedSuggestionBuilder(request); | |
| 125 } | |
| 126 return null; | |
| 127 } | |
| 128 | |
| 129 @override | |
| 130 _ImportedSuggestionBuilder visitIfStatement(IfStatement node) { | |
| 131 Token leftParen = node.leftParenthesis; | |
| 132 if (leftParen != null && request.offset >= leftParen.end) { | |
| 133 Token rightParen = node.rightParenthesis; | |
| 134 if (rightParen == null || request.offset <= rightParen.offset) { | |
| 135 return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true); | |
| 136 } | |
| 137 } | |
| 138 return null; | |
| 139 } | |
| 140 | |
| 141 @override | |
| 142 _ImportedSuggestionBuilder | |
| 143 visitInterpolationExpression(InterpolationExpression node) { | |
| 144 Expression expression = node.expression; | |
| 145 if (expression is SimpleIdentifier) { | |
| 146 return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true); | |
| 147 } | |
| 148 return null; | |
| 149 } | |
| 150 | |
| 151 @override | |
| 152 _ImportedSuggestionBuilder visitMethodInvocation(MethodInvocation node) { | |
| 153 Token period = node.period; | |
| 154 if (period == null || request.offset <= period.offset) { | |
| 155 return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true); | |
| 156 } | |
| 157 return null; | |
| 158 } | |
| 159 | |
| 160 @override | |
| 161 _ImportedSuggestionBuilder visitNode(AstNode node) { | |
| 162 return null; | |
| 163 } | |
| 164 | |
| 165 @override | |
| 166 _ImportedSuggestionBuilder visitPrefixedIdentifier(PrefixedIdentifier node) { | |
| 167 // Make suggestions for the prefix, but not for the selector | |
| 168 // InvocationComputer makes selector suggestions | |
| 169 Token period = node.period; | |
| 170 if (period == null || request.offset <= period.offset) { | |
| 171 return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true); | |
| 172 } | |
| 173 return null; | |
| 174 } | |
| 175 | |
| 176 @override | |
| 177 _ImportedSuggestionBuilder visitPropertyAccess(PropertyAccess node) { | |
| 178 // Make suggestions for the target, but not for the property name | |
| 179 // InvocationComputer makes property name suggestions | |
| 180 var operator = node.operator; | |
| 181 if (operator != null && request.offset < operator.offset) { | |
| 182 return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true); | |
| 183 } | |
| 184 return null; | |
| 185 } | |
| 186 | |
| 187 @override | |
| 188 _ImportedSuggestionBuilder visitSimpleIdentifier(SimpleIdentifier node) { | |
| 189 return node.parent.accept(this); | |
| 190 } | |
| 191 | |
| 192 @override | |
| 193 _ImportedSuggestionBuilder visitStringLiteral(StringLiteral node) { | |
| 194 return null; | |
| 195 } | |
| 196 | |
| 197 @override | |
| 198 _ImportedSuggestionBuilder visitTypeName(TypeName node) { | |
| 199 // TODO (danrubel) refactor this and local_computer | |
| 200 // to reduce duplicate code | |
| 201 bool typesOnly = false; | |
| 202 // If suggesting completions within a TypeName node | |
| 203 // then limit suggestions to only types in specific situations | |
| 204 AstNode p = node.parent; | |
| 205 if (p is IsExpression || p is ConstructorName || p is AsExpression) { | |
| 206 typesOnly = true; | |
| 207 } else if (p is VariableDeclarationList) { | |
| 208 // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS | |
| 209 // the user may be either (1) entering a type for the assignment | |
| 210 // or (2) starting a new statement. | |
| 211 // Consider suggesting only types | |
| 212 // if only spaces separates the 1st and 2nd identifiers. | |
| 213 } | |
| 214 return new _ImportedSuggestionBuilder(request, typesOnly: typesOnly); | |
| 215 } | |
| 216 | |
| 217 @override | |
| 218 _ImportedSuggestionBuilder | |
| 219 visitVariableDeclaration(VariableDeclaration node) { | |
| 220 Token equals = node.equals; | |
| 221 // Make suggestions for the RHS of a variable declaration | |
| 222 if (equals != null && request.offset >= equals.end) { | |
| 223 return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true); | |
| 224 } | |
| 225 return null; | |
| 226 } | |
| 227 } | |
| 228 | |
| 229 /** | |
| 230 * [_ImportedSuggestionBuilder] traverses the imports and builds suggestions | 59 * [_ImportedSuggestionBuilder] traverses the imports and builds suggestions |
| 231 * based upon imported elements. | 60 * based upon imported elements. |
| 232 */ | 61 */ |
| 233 class _ImportedSuggestionBuilder implements SuggestionBuilder { | 62 class _ImportedSuggestionBuilder implements SuggestionBuilder { |
| 234 bool shouldWaitForLowPrioritySuggestions; | 63 bool shouldWaitForLowPrioritySuggestions; |
| 235 final DartCompletionRequest request; | 64 final DartCompletionRequest request; |
| 236 final bool typesOnly; | 65 final bool typesOnly; |
| 237 final bool excludeVoidReturn; | 66 final bool excludeVoidReturn; |
| 238 DartCompletionCache cache; | 67 DartCompletionCache cache; |
| 239 | 68 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 367 addFilteredSuggestions(cache.importedTypeSuggestions); | 196 addFilteredSuggestions(cache.importedTypeSuggestions); |
| 368 addFilteredSuggestions(cache.libraryPrefixSuggestions); | 197 addFilteredSuggestions(cache.libraryPrefixSuggestions); |
| 369 if (!typesOnly) { | 198 if (!typesOnly) { |
| 370 addFilteredSuggestions(cache.otherImportedSuggestions); | 199 addFilteredSuggestions(cache.otherImportedSuggestions); |
| 371 if (!excludeVoidReturn) { | 200 if (!excludeVoidReturn) { |
| 372 addFilteredSuggestions(cache.importedVoidReturnSuggestions); | 201 addFilteredSuggestions(cache.importedVoidReturnSuggestions); |
| 373 } | 202 } |
| 374 } | 203 } |
| 375 } | 204 } |
| 376 } | 205 } |
| OLD | NEW |