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

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

Issue 1355173002: Remove old translated code from DAS. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 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
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/generated/stubs.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information.
7
8 library services.completion;
9
10 import 'dart:collection';
11 import "dart:math" as math;
12
13 import 'package:analysis_server/src/protocol.dart'
14 show CompletionSuggestionKind;
15 import 'package:analyzer/src/generated/java_core.dart' hide StringUtils;
16 import 'package:analyzer/src/generated/java_engine.dart';
17 import 'package:analyzer/src/generated/java_io.dart';
18 import 'package:analyzer/src/generated/ast.dart';
19 import 'package:analyzer/src/generated/element.dart';
20 import 'package:analyzer/src/generated/engine.dart';
21 import 'package:analyzer/src/generated/error.dart';
22 import 'package:analyzer/src/generated/resolver.dart';
23 import 'package:analyzer/src/generated/scanner.dart';
24 import 'package:analyzer/src/generated/sdk.dart';
25 import 'package:analyzer/src/generated/source_io.dart';
26 import 'package:analyzer/src/generated/utilities_dart.dart';
27
28 import 'stubs.dart';
29 import 'util.dart';
30
31 class AstNodeClassifier_CompletionEngine_typeOf extends CompletionEngine_AstNode Classifier {
32 final CompletionEngine CompletionEngine_this;
33
34 DartType result = null;
35
36 AstNodeClassifier_CompletionEngine_typeOf(this.CompletionEngine_this);
37
38 @override
39 Object visitPrefixedIdentifier(PrefixedIdentifier node) => visitSimpleIdentifi er(node.identifier);
40
41 @override
42 Object visitSimpleIdentifier(SimpleIdentifier node) {
43 Element elem = node.bestElement;
44 if (elem != null && elem.kind == ElementKind.GETTER) {
45 PropertyAccessorElement accessor = elem as PropertyAccessorElement;
46 if (accessor.isSynthetic) {
47 PropertyInducingElement var2 = accessor.variable;
48 result = CompletionEngine_this._typeSearch(var2);
49 }
50 }
51 return null;
52 }
53 }
54
55 /**
56 * The analysis engine for code completion.
57 *
58 * Note: During development package-private methods are used to group element-sp ecific completion
59 * utilities.
60 *
61 * TODO: Recognize when completion is requested in the middle of a multi-charact er operator.
62 * Re-write the AST as it would be if an identifier were present at the completi on point then
63 * restart the analysis.
64 */
65 class CompletionEngine {
66 static String _C_DYNAMIC = "dynamic";
67
68 static String _C_FALSE = "false";
69
70 static String _C_NULL = "null";
71
72 static String _C_PARAMNAME = "arg";
73
74 static String _C_TRUE = "true";
75
76 static String _C_VAR = "var";
77
78 static String _C_VOID = "void";
79
80 static bool _isPrivate(Element element) {
81 String name = element.displayName;
82 return Identifier.isPrivateName(name);
83 }
84
85 static bool _isSyntheticIdentifier(Expression expression) => expression is Sim pleIdentifier && expression.isSynthetic;
86
87 CompletionRequestor _requestor;
88
89 final CompletionFactory _factory;
90
91 AssistContext _context;
92
93 Filter _filter;
94
95 CompletionState _state;
96
97 List<LibraryElement> _libraries;
98
99 CompletionEngine(CompletionRequestor requestor, this._factory) {
100 this._requestor = requestor;
101 this._state = new CompletionState();
102 }
103
104 /**
105 * Analyze the source unit in the given context to determine completion propos als at the selection
106 * offset of the context.
107 *
108 * @throws Exception
109 */
110 void complete(AssistContext context) {
111 this._context = context;
112 _requestor.beginReporting();
113 AstNode completionNode = context.coveredNode;
114 if (completionNode != null) {
115 _state.context = completionNode;
116 CompletionEngine_TerminalNodeCompleter visitor = new CompletionEngine_Term inalNodeCompleter(this);
117 completionNode.accept(visitor);
118 }
119 _requestor.endReporting();
120 }
121
122 void _analyzeAnnotationName(SimpleIdentifier identifier) {
123 _filter = _createFilter(identifier);
124 CompletionEngine_NameCollector names = _collectTopLevelElementVisibleAt(iden tifier);
125 for (Element element in names.uniqueElements) {
126 if (element is PropertyAccessorElement) {
127 element = (element as PropertyAccessorElement).variable;
128 }
129 if (element is TopLevelVariableElement) {
130 TopLevelVariableElement variable = element as TopLevelVariableElement;
131 if (_state._isCompileTimeConstantRequired && !variable.isConst) {
132 continue;
133 }
134 _proposeName(element, identifier, names);
135 }
136 if (element is ClassElement) {
137 ClassElement classElement = element as ClassElement;
138 for (ConstructorElement constructor in classElement.constructors) {
139 _pNamedConstructor(classElement, constructor, identifier);
140 }
141 }
142 }
143 }
144
145 void _analyzeConstructorTypeName(SimpleIdentifier identifier) {
146 _filter = _createFilter(identifier);
147 List<Element> types = _findAllTypes(currentLibrary, TopLevelNamesKind.DECLAR ED_AND_IMPORTS);
148 for (Element type in types) {
149 if (type is ClassElement) {
150 _namedConstructorReference(type, identifier);
151 }
152 }
153 List<Element> prefixes = _findAllPrefixes();
154 for (Element prefix in prefixes) {
155 _pName(prefix, identifier);
156 }
157 }
158
159 void _analyzeDeclarationName(VariableDeclaration varDecl) {
160 // We might want to propose multiple names for a declaration based on types someday.
161 // For now, just use whatever is already there.
162 SimpleIdentifier identifier = varDecl.name;
163 _filter = _createFilter(identifier);
164 VariableDeclarationList varList = varDecl.parent as VariableDeclarationList;
165 TypeName type = varList.type;
166 if (identifier.length > 0) {
167 _pName3(identifier.name, CompletionSuggestionKind.LOCAL_VARIABLE);
168 }
169 if (type == null) {
170 if (varList.keyword == null) {
171 // Interpret as the type name of a typed variable declaration { DivE!; }
172 _analyzeLocalName(identifier);
173 }
174 } else {
175 _pParamName(type.name.name.toLowerCase());
176 }
177 }
178
179 void _analyzeDirectAccess(DartType receiverType, SimpleIdentifier completionNo de) {
180 if (receiverType != null) {
181 // Complete this.!y where this is absent
182 Element rcvrTypeElem = receiverType.element;
183 if (receiverType.isDynamic) {
184 rcvrTypeElem = objectClassElement;
185 }
186 if (rcvrTypeElem is ClassElement) {
187 _directAccess(rcvrTypeElem as ClassElement, completionNode);
188 }
189 }
190 }
191
192 void _analyzeImmediateField(SimpleIdentifier fieldName) {
193 _filter = _createFilter(fieldName);
194 ClassDeclaration classDecl = fieldName.getAncestor((node) => node is ClassDe claration);
195 ClassElement classElement = classDecl.element;
196 for (FieldElement field in classElement.fields) {
197 _pName3(field.displayName, CompletionSuggestionKind.FIELD);
198 }
199 }
200
201 void _analyzeLiteralReference(BooleanLiteral literal) {
202 // state.setContext(literal);
203 Ident ident = _createIdent(literal.parent);
204 ident.token = literal.literal;
205 _filter = _createFilter(ident);
206 _analyzeLocalName(ident);
207 }
208
209 void _analyzeLocalName(SimpleIdentifier identifier) {
210 // Completion x!
211 _filter = _createFilter(identifier);
212 // TODO Filter out types that have no static members.
213 CompletionEngine_NameCollector names = _collectIdentifiersVisibleAt(identifi er);
214 for (Element element in names.uniqueElements) {
215 if (_state._isSourceDeclarationStatic) {
216 if (element is FieldElement) {
217 if (!element.isStatic) {
218 continue;
219 }
220 } else if (element is PropertyAccessorElement) {
221 if (!element.isStatic) {
222 continue;
223 }
224 }
225 }
226 if (_state._isOptionalArgumentRequired) {
227 if (element is! ParameterElement) {
228 continue;
229 }
230 ParameterElement param = element as ParameterElement;
231 if (!param.parameterKind.isOptional) {
232 continue;
233 }
234 }
235 _proposeName(element, identifier, names);
236 }
237 if (_state._areLiteralsAllowed) {
238 _pNull();
239 _pTrue();
240 _pFalse();
241 }
242 }
243
244 void _analyzeNamedParameter(ArgumentList args, SimpleIdentifier identifier) {
245 // Completion x!
246 _filter = _createFilter(identifier);
247 // prepare parameters
248 List<ParameterElement> parameters = _getParameterElements(args);
249 if (parameters == null) {
250 return;
251 }
252 // remember already used names
253 Set<String> usedNames = new Set();
254 for (Expression arg in args.arguments) {
255 if (arg is NamedExpression) {
256 NamedExpression namedExpr = arg;
257 String name = namedExpr.name.label.name;
258 usedNames.add(name);
259 }
260 }
261 // propose named parameters
262 for (ParameterElement parameterElement in parameters) {
263 // should be named
264 if (parameterElement.parameterKind != ParameterKind.NAMED) {
265 continue;
266 }
267 // filter by name
268 if (_filterDisallows(parameterElement)) {
269 continue;
270 }
271 // may be already used
272 String parameterName = parameterElement.name;
273 if (usedNames.contains(parameterName)) {
274 continue;
275 }
276 // OK, add proposal
277 CompletionProposal prop = _createProposal4(CompletionSuggestionKind.NAMED_ ARGUMENT);
278 prop.setCompletion(parameterName);
279 prop.setParameterName(parameterName);
280 prop.setParameterType(parameterElement.type.displayName);
281 prop.setLocation(identifier.offset);
282 prop.setReplacementLength(identifier.length);
283 prop.setRelevance(CompletionProposal.RELEVANCE_HIGH);
284 _requestor.accept(prop);
285 }
286 }
287
288 void _analyzeNewParameterName(List<FormalParameter> params, SimpleIdentifier t ypeIdent, String identifierName) {
289 String typeName = typeIdent.name;
290 _filter = _createFilter(_createIdent(typeIdent));
291 List<String> names = new List<String>();
292 for (FormalParameter node in params) {
293 names.add(node.identifier.name);
294 }
295 // Find name similar to typeName not in names, ditto for identifierName.
296 if (identifierName == null || identifierName.isEmpty) {
297 String candidate = typeName == null || typeName.isEmpty ? _C_PARAMNAME : t ypeName.toLowerCase();
298 _pParamName(_makeNonconflictingName(candidate, names));
299 } else {
300 _pParamName(_makeNonconflictingName(identifierName, names));
301 if (typeName != null && !typeName.isEmpty) {
302 _pParamName(_makeNonconflictingName(typeName.toLowerCase(), names));
303 }
304 }
305 }
306
307 void _analyzePositionalArgument(ArgumentList args, SimpleIdentifier identifier ) {
308 // Show parameter name only if there is nothing to complete, so that if ther e is only
309 // one match, we won't to force user to choose.
310 if (!StringUtils.isEmpty(identifier.name)) {
311 return;
312 }
313 // prepare parameters
314 List<ParameterElement> parameters = _getParameterElements(args);
315 if (parameters == null) {
316 return;
317 }
318 // show current parameter
319 int argIndex = args.arguments.indexOf(identifier);
320 if (argIndex == -1) {
321 argIndex = 0;
322 }
323 if (argIndex >= 0 && argIndex < parameters.length) {
324 ParameterElement parameter = parameters[argIndex];
325 if (parameter.parameterKind != ParameterKind.NAMED) {
326 String parameterName = parameter.displayName;
327 CompletionProposal prop = _createProposal4(CompletionSuggestionKind.OPTI ONAL_ARGUMENT);
328 prop.setCompletion(parameterName);
329 prop.setParameterName(parameterName);
330 prop.setParameterType(parameter.type.displayName);
331 prop.setLocation(identifier.offset);
332 prop.setReplacementLength(identifier.length);
333 prop.setRelevance(CompletionProposal.RELEVANCE_HIGH);
334 _requestor.accept(prop);
335 }
336 }
337 }
338
339 void _analyzePrefixedAccess(Expression receiver, SimpleIdentifier completionNo de) {
340 if (receiver is ThisExpression && !_state._isThisAllowed) {
341 return;
342 }
343 DartType receiverType = _typeOf2(receiver);
344 bool forSuper = receiver is SuperExpression;
345 _analyzePrefixedAccess2(receiverType, forSuper, completionNode);
346 }
347
348 void _analyzePrefixedAccess2(DartType receiverType, bool forSuper, SimpleIdent ifier completionNode) {
349 if (receiverType != null) {
350 // Complete x.!y
351 Element rcvrTypeElem = receiverType.element;
352 if (receiverType.isBottom) {
353 receiverType = objectType;
354 }
355 if (receiverType.isDynamic) {
356 receiverType = objectType;
357 }
358 if (receiverType is InterfaceType) {
359 _prefixedAccess(receiverType, forSuper, completionNode);
360 } else if (rcvrTypeElem is TypeParameterElement) {
361 TypeParameterElement typeParamElem = rcvrTypeElem;
362 _analyzePrefixedAccess2(typeParamElem.bound, false, completionNode);
363 }
364 }
365 }
366
367 void _analyzeReceiver(SimpleIdentifier identifier) {
368 // Completion x!.y
369 _filter = _createFilter(identifier);
370 CompletionEngine_NameCollector names = _collectIdentifiersVisibleAt(identifi er);
371 for (Element element in names.uniqueElements) {
372 _proposeName(element, identifier, names);
373 }
374 }
375
376 void _analyzeSuperConstructorInvocation(SuperConstructorInvocation node) {
377 ClassDeclaration enclosingClassNode = node.getAncestor((node) => node is Cla ssDeclaration);
378 if (enclosingClassNode != null) {
379 ClassElement enclosingClassElement = enclosingClassNode.element;
380 if (enclosingClassElement != null) {
381 ClassElement superClassElement = enclosingClassElement.supertype.element ;
382 _constructorReference(superClassElement, node.constructorName);
383 }
384 }
385 }
386
387 void _analyzeTypeName(SimpleIdentifier identifier, SimpleIdentifier nameIdent) {
388 _filter = _createFilter(identifier);
389 String name = nameIdent == null ? "" : nameIdent.name;
390 List<Element> types = _findAllTypes(currentLibrary, TopLevelNamesKind.DECLAR ED_AND_IMPORTS);
391 for (Element type in types) {
392 if (_state._isForMixin) {
393 if (type is! ClassElement) {
394 continue;
395 }
396 ClassElement classElement = type as ClassElement;
397 if (!classElement.isValidMixin) {
398 continue;
399 }
400 }
401 if (type.displayName == name) {
402 continue;
403 }
404 _pName(type, nameIdent);
405 }
406 if (!_state._isForMixin) {
407 ClassDeclaration classDecl = identifier.getAncestor((node) => node is Clas sDeclaration);
408 if (classDecl != null) {
409 ClassElement classElement = classDecl.element;
410 for (TypeParameterElement param in classElement.typeParameters) {
411 _pName(param, nameIdent);
412 }
413 }
414 }
415 List<Element> prefixes = _findAllPrefixes();
416 for (Element prefix in prefixes) {
417 _pName(prefix, nameIdent);
418 }
419 if (_state._isDynamicAllowed) {
420 _pDynamic();
421 }
422 if (_state._isVarAllowed) {
423 _pVar();
424 }
425 if (_state._isVoidAllowed) {
426 _pVoid();
427 }
428 }
429
430 void _constructorReference(ClassElement classElement, SimpleIdentifier identif ier) {
431 // Complete identifier when it refers to a constructor defined in classEleme nt.
432 _filter = _createFilter(identifier);
433 for (ConstructorElement cons in classElement.constructors) {
434 if (_state._isCompileTimeConstantRequired == cons.isConst && _filterAllows (cons)) {
435 _pExecutable2(cons, identifier, false);
436 }
437 }
438 }
439
440 void _directAccess(ClassElement classElement, SimpleIdentifier identifier) {
441 _filter = _createFilter(identifier);
442 CompletionEngine_NameCollector names = _createNameCollector();
443 names.addLocalNames(identifier);
444 names._addNamesDefinedByHierarchy(classElement, false);
445 names._addTopLevelNames2(currentLibrary, TopLevelNamesKind.DECLARED_AND_IMPO RTS);
446 _proposeNames(names, identifier);
447 }
448
449 void _dispatchPrefixAnalysis(InstanceCreationExpression node) {
450 // prepare ClassElement
451 ClassElement classElement;
452 {
453 Element typeElement = _typeOf2(node).element;
454 if (typeElement is! ClassElement) {
455 return;
456 }
457 classElement = typeElement as ClassElement;
458 }
459 // prepare constructor name
460 Identifier typeName = node.constructorName.type.name;
461 SimpleIdentifier identifier = null;
462 if (typeName is SimpleIdentifier) {
463 identifier = typeName;
464 } else if (typeName is PrefixedIdentifier) {
465 identifier = typeName.identifier;
466 }
467 if (identifier == null) {
468 identifier = _createIdent(node);
469 }
470 // analyze constructor name
471 _analyzeConstructorTypeName(identifier);
472 _constructorReference(classElement, identifier);
473 }
474
475 void _dispatchPrefixAnalysis2(MethodInvocation node) {
476 // This might be a library prefix on a top-level function
477 Expression expr = node.realTarget;
478 if (expr is SimpleIdentifier) {
479 SimpleIdentifier ident = expr;
480 if (ident.bestElement is PrefixElement) {
481 _prefixedAccess2(ident, node.methodName);
482 return;
483 } else if (ident.bestElement is ClassElement) {
484 _state._areInstanceReferencesProhibited = true;
485 _state._areStaticReferencesProhibited = false;
486 } else {
487 _state._areInstanceReferencesProhibited = false;
488 _state._areStaticReferencesProhibited = true;
489 }
490 }
491 if (expr == null) {
492 _analyzeLocalName(_createIdent(node));
493 } else {
494 _analyzePrefixedAccess(expr, node.methodName);
495 }
496 }
497
498 void _dispatchPrefixAnalysis3(PrefixedIdentifier node, SimpleIdentifier identi fier) {
499 SimpleIdentifier receiverName = node.prefix;
500 Element receiver = receiverName.bestElement;
501 if (receiver == null) {
502 _prefixedAccess2(receiverName, identifier);
503 return;
504 }
505 while (true) {
506 if (receiver.kind == ElementKind.PREFIX || receiver.kind == ElementKind.IM PORT) {
507 // Complete lib_prefix.name
508 _prefixedAccess2(receiverName, identifier);
509 } else {
510 {
511 DartType receiverType;
512 DartType propType = _typeOf2(receiverName);
513 if (propType == null || propType.isDynamic) {
514 receiverType = _typeOf(receiver);
515 } else {
516 DartType declType = _typeOf(receiver);
517 if (propType.isMoreSpecificThan(declType)) {
518 receiverType = propType;
519 } else {
520 receiverType = declType;
521 }
522 }
523 _analyzePrefixedAccess2(receiverType, false, identifier);
524 break;
525 }
526 }
527 break;
528 }
529 }
530
531 void _fieldReference(ClassElement classElement, SimpleIdentifier identifier) {
532 // Complete identifier when it refers to a constructor defined in classEleme nt.
533 _filter = _createFilter(identifier);
534 for (FieldElement cons in classElement.fields) {
535 if (_filterAllows(cons)) {
536 _pField(cons, identifier, classElement);
537 }
538 }
539 }
540
541 void _namedConstructorReference(ClassElement classElement, SimpleIdentifier id entifier) {
542 // Complete identifier when it refers to a named constructor defined in clas sElement.
543 if (_filter == null) {
544 _filter = _createFilter(identifier);
545 }
546 for (ConstructorElement cons in classElement.constructors) {
547 if (!_isVisible(cons)) {
548 continue;
549 }
550 if (_state._isCompileTimeConstantRequired && !cons.isConst) {
551 continue;
552 }
553 _pNamedConstructor(classElement, cons, identifier);
554 }
555 }
556
557 void _namespacePubReference(NamespaceDirective node, Set<String> packageUris) {
558 // no import URI or package:
559 String prefix = _filter._prefix;
560 List<String> prefixStrings = prefix.split(":");
561 if (!prefix.isEmpty && !"package:".startsWith(prefixStrings[0])) {
562 return;
563 }
564 // if no URI yet, propose package:
565 if (prefix.isEmpty) {
566 _pImportUriWithScheme(node, "package:");
567 return;
568 }
569 // check "packages" folder for package libraries that are not added to Analy sisContext
570 {
571 Source contextSource = _context.source;
572 if (contextSource is FileBasedSource) {
573 FileBasedSource contextFileSource = contextSource;
574 String contextFilePath = contextFileSource.fullName;
575 JavaFile contextFile = new JavaFile(contextFilePath);
576 JavaFile contextFolder = contextFile.getParentFile();
577 JavaFile contextPackages = new JavaFile.relative(contextFolder, "package s");
578 if (contextPackages.isDirectory()) {
579 for (JavaFile packageFolder in contextPackages.listFiles()) {
580 String packageName = packageFolder.getName();
581 String packageLibName = "${packageName}.dart";
582 JavaFile packageFile = new JavaFile.relative(packageFolder, packageL ibName);
583 if (packageFile.exists() && packageFile.isFile()) {
584 packageUris.add("package:${packageName}/${packageLibName}");
585 }
586 }
587 }
588 }
589 }
590 // add known package: URIs
591 for (String uri in packageUris) {
592 if (_filterDisallows2(uri)) {
593 continue;
594 }
595 CompletionProposal prop = _createProposal4(CompletionSuggestionKind.IMPORT );
596 prop.setCompletion(uri);
597 // put "lib" before "lib/src"
598 if (!uri.contains("/src/")) {
599 prop.setRelevance(CompletionProposal.RELEVANCE_HIGH);
600 }
601 // done
602 _requestor.accept(prop);
603 }
604 }
605
606 void _namespaceReference(NamespaceDirective node, SimpleStringLiteral literal) {
607 String lit = literal.literal.lexeme;
608 if (!lit.isEmpty) {
609 lit = lit.substring(1, math.max(lit.length - 1, 0));
610 }
611 _filter = _createFilter(new Ident.con2(node, lit, literal.offset + 1));
612 Set<String> packageUris = new Set();
613 List<LibraryElement> libraries = new List<LibraryElement>();
614 List<LibraryElement> librariesInLib = new List<LibraryElement>();
615 String currentLibraryName = currentLibrary.source.fullName;
616 AnalysisContext ac = analysisContext;
617 List<Source> sources = ac.librarySources;
618 for (Source s in sources) {
619 String sName = s.fullName;
620 // skip current library
621 if (currentLibraryName == sName) {
622 continue;
623 }
624 // ".pub-cache/..../unittest-0.8.8/lib/unittest.dart" -> "package:unittest /unittest.dart"
625 {
626 Uri uri = ac.sourceFactory.restoreUri(s);
627 if (uri != null) {
628 String uriString = uri.toString();
629 if (uriString.startsWith("package:")) {
630 packageUris.add(uriString);
631 }
632 }
633 }
634 LibraryElement lib = ac.getLibraryElement(s);
635 if (lib == null) {
636 continue;
637 } else if (_isUnitInLibFolder(lib.definingCompilationUnit)) {
638 librariesInLib.add(lib);
639 } else {
640 libraries.add(lib);
641 }
642 }
643 _namespaceSdkReference(node);
644 _namespacePubReference(node, packageUris);
645 }
646
647 void _namespaceSdkReference(NamespaceDirective node) {
648 String prefix = _filter._prefix;
649 List<String> prefixStrings = prefix.split(":");
650 if (!prefix.isEmpty && !"dart:".startsWith(prefixStrings[0])) {
651 return;
652 }
653 if (prefix.isEmpty) {
654 _pImportUriWithScheme(node, "dart:");
655 return;
656 }
657 // add DartSdk libraries
658 DartSdk dartSdk = analysisContext.sourceFactory.dartSdk;
659 for (SdkLibrary library in dartSdk.sdkLibraries) {
660 String name = library.shortName;
661 // ignore internal
662 if (library.isInternal) {
663 continue;
664 }
665 // ignore implementation
666 if (library.isImplementation) {
667 continue;
668 }
669 // standard libraries name name starting with "dart:"
670 name = StringUtils.removeStart(name, "dart:");
671 // ignore private libraries
672 if (Identifier.isPrivateName(name)) {
673 continue;
674 }
675 // add with "dart:" prefix
676 _pName3("dart:${name}", CompletionSuggestionKind.IMPORT);
677 }
678 }
679
680 void _operatorAccess(Expression expr, SimpleIdentifier identifier) {
681 _state._requiresOperators();
682 _analyzePrefixedAccess(expr, identifier);
683 }
684
685 void _prefixedAccess(InterfaceType type, bool forSuper, SimpleIdentifier ident ifier) {
686 // Complete identifier when it refers to field or method in classElement.
687 _filter = _createFilter(identifier);
688 CompletionEngine_NameCollector names = _createNameCollector();
689 if (_state._areInstanceReferencesProhibited) {
690 names._addNamesDefinedByType2(type);
691 } else {
692 names._addNamesDefinedByHierarchy2(type, forSuper);
693 }
694 _proposeNames(names, identifier);
695 }
696
697 void _prefixedAccess2(SimpleIdentifier prefixName, SimpleIdentifier identifier ) {
698 if (_filter == null) {
699 _filter = _createFilter(identifier);
700 }
701 CompletionEngine_NameCollector names = _createNameCollector();
702 List<ImportElement> prefixImports = _importsWithName(prefixName);
703 // Library prefixes do not have a unique AST representation so we need to fu dge state vars.
704 bool litsAllowed = _state._areLiteralsAllowed;
705 _state._areLiteralsAllowed = false;
706 names._addTopLevelNames(prefixImports, TopLevelNamesKind.DECLARED_AND_EXPORT S);
707 _state._areLiteralsAllowed = litsAllowed;
708 _proposeNames(names, identifier);
709 }
710
711 List<InterfaceType> _allSubtypes(ClassElement classElement) {
712 // TODO(scheglov) translate it
713 return [];
714 }
715
716 CompletionEngine_NameCollector _collectIdentifiersVisibleAt(AstNode ident) {
717 CompletionEngine_NameCollector names = _createNameCollector();
718 ScopedNameFinder finder = new ScopedNameFinder(_completionLocation());
719 ident.accept(finder);
720 names.addAll(finder.locals.values);
721 Declaration decl = finder.declaration;
722 if (decl != null && decl.parent is ClassDeclaration) {
723 ClassElement classElement = (decl.parent as ClassDeclaration).element;
724 names._addNamesDefinedByHierarchy(classElement, false);
725 }
726 names._addTopLevelNames2(currentLibrary, TopLevelNamesKind.DECLARED_AND_IMPO RTS);
727 return names;
728 }
729
730 CompletionEngine_NameCollector _collectTopLevelElementVisibleAt(AstNode ident) {
731 CompletionEngine_NameCollector names = _createNameCollector();
732 names._addTopLevelNames2(currentLibrary, TopLevelNamesKind.DECLARED_AND_IMPO RTS);
733 return names;
734 }
735
736 int _completionLocation() => _context.selectionOffset;
737
738 int _completionTokenOffset() => _completionLocation() - _filter._prefix.length ;
739
740 List<FormalParameter> _copyWithout(NodeList oldList, AstNode deletion) {
741 List<FormalParameter> newList = new List<FormalParameter>();
742 oldList.accept(new GeneralizingAstVisitor_CompletionEngine_copyWithout(delet ion, newList));
743 return newList;
744 }
745
746 Filter _createFilter(SimpleIdentifier ident) => new Filter.con1(ident, _contex t.selectionOffset);
747
748 Ident _createIdent(AstNode node) => new Ident.con1(node, _completionLocation() );
749
750 CompletionEngine_NameCollector _createNameCollector() => new CompletionEngine_ NameCollector(this);
751
752 CompletionProposal _createProposal(Element element) {
753 String completion = element.displayName;
754 return _createProposal3(element, completion);
755 }
756
757 CompletionProposal _createProposal2(Element element, SimpleIdentifier identifi er) {
758 // Create a completion proposal for the element: variable, field, class, fun ction.
759 if (_filterDisallows(element)) {
760 return null;
761 }
762 CompletionProposal prop = _createProposal(element);
763 Element container = element.enclosingElement;
764 if (container != null) {
765 prop.setDeclaringType(container.displayName);
766 }
767 DartType type = _typeOf(element);
768 if (type != null) {
769 prop.setReturnType(type.name);
770 }
771 if (identifier != null) {
772 prop.setReplacementLengthIdentifier(identifier.length);
773 }
774 return prop;
775 }
776
777 CompletionProposal _createProposal3(Element element, String completion) {
778 CompletionSuggestionKind kind = _proposalKindOf(element);
779 CompletionProposal prop = _createProposal4(kind);
780 prop.setElement(element);
781 prop.setCompletion(completion);
782 prop.setDeprecated(_isDeprecated(element));
783 if (_isPrivate(element)) {
784 prop.setRelevance(CompletionProposal.RELEVANCE_LOW);
785 }
786 if (_filter._isSameCasePrefix(element.name)) {
787 prop.incRelevance();
788 }
789 return prop;
790 }
791
792 CompletionProposal _createProposal4(CompletionSuggestionKind kind) => _factory .createCompletionProposal(kind, _completionTokenOffset());
793
794 List<LibraryElement> _currentLibraryList() {
795 Set<LibraryElement> libraries = new Set<LibraryElement>();
796 LibraryElement curLib = currentLibrary;
797 libraries.add(curLib);
798 Queue<LibraryElement> queue = new Queue<LibraryElement>();
799 queue.addAll(curLib.importedLibraries);
800 _currentLibraryLister(queue, libraries);
801 return new List.from(libraries);
802 }
803
804 void _currentLibraryLister(Queue<LibraryElement> queue, Set<LibraryElement> li braries) {
805 while (!queue.isEmpty) {
806 LibraryElement sourceLib = queue.removeFirst();
807 libraries.add(sourceLib);
808 List<LibraryElement> expLibs = sourceLib.exportedLibraries;
809 for (LibraryElement lib in expLibs) {
810 if (!libraries.contains(lib)) {
811 queue.add(lib);
812 }
813 }
814 }
815 }
816
817 bool _filterAllows(Element element) => _filter._match(element);
818
819 bool _filterDisallows(Element element) => !_filter._match(element);
820
821 bool _filterDisallows2(String name) => !_filter._match2(name);
822
823 List<Element> _findAllNotTypes(List<Element> elements) {
824 return elements.where((Element element) {
825 ElementKind kind = element.kind;
826 return kind == ElementKind.FUNCTION
827 || kind == ElementKind.TOP_LEVEL_VARIABLE
828 || kind == ElementKind.GETTER
829 || kind == ElementKind.SETTER;
830 }).toList();
831 }
832
833 List<Element> _findAllPrefixes() {
834 LibraryElement lib = _context.compilationUnitElement.enclosingElement;
835 return lib.prefixes;
836 }
837
838 List<Element> _findAllTypes(LibraryElement library, TopLevelNamesKind topKind) {
839 List<Element> elements = _findTopLevelElements(library, topKind);
840 return _findAllTypes2(elements);
841 }
842
843 List<Element> _findAllTypes2(List<Element> elements) {
844 return elements.where((Element element) {
845 ElementKind kind = element.kind;
846 return kind == ElementKind.CLASS
847 || kind == ElementKind.FUNCTION_TYPE_ALIAS;
848 }).toList();
849 }
850
851 List<Element> _findTopLevelElements(LibraryElement library, TopLevelNamesKind topKind) {
852 List<Element> elements = [];
853 if (topKind == TopLevelNamesKind.DECLARED_AND_IMPORTS) {
854 elements.addAll(CorrectionUtils.getTopLevelElements(library));
855 for (ImportElement imp in library.imports) {
856 elements.addAll(CorrectionUtils.getImportNamespace(imp).values);
857 }
858 _removeNotMatchingFilter(elements);
859 }
860 if (topKind == TopLevelNamesKind.DECLARED_AND_EXPORTS) {
861 elements.addAll(CorrectionUtils.getExportNamespace2(library).values);
862 _removeNotMatchingFilter(elements);
863 }
864 return elements;
865 }
866
867 AnalysisContext get analysisContext => _context.compilationUnitElement.context ;
868
869 LibraryElement get currentLibrary => _context.compilationUnitElement.enclosing Element;
870
871 FunctionType _getFunctionType(Element element) {
872 if (element is ExecutableElement) {
873 ExecutableElement executableElement = element;
874 return executableElement.type;
875 }
876 if (element is VariableElement) {
877 VariableElement variableElement = element;
878 DartType type = variableElement.type;
879 if (type is FunctionType) {
880 return type;
881 }
882 }
883 return null;
884 }
885
886 ClassElement get objectClassElement => typeProvider.objectType.element;
887
888 InterfaceType get objectType => typeProvider.objectType;
889
890 List<ParameterElement> _getParameterElements(ArgumentList args) {
891 List<ParameterElement> parameters = null;
892 AstNode argsParent = args.parent;
893 if (argsParent is MethodInvocation) {
894 MethodInvocation invocation = argsParent;
895 Element nameElement = invocation.methodName.staticElement;
896 FunctionType functionType = _getFunctionType(nameElement);
897 if (functionType != null) {
898 parameters = functionType.parameters;
899 }
900 }
901 if (argsParent is InstanceCreationExpression) {
902 InstanceCreationExpression creation = argsParent;
903 ConstructorElement element = creation.staticElement;
904 if (element != null) {
905 parameters = element.parameters;
906 }
907 }
908 if (argsParent is Annotation) {
909 Annotation annotation = argsParent;
910 Element element = annotation.element;
911 if (element is ConstructorElement) {
912 parameters = element.parameters;
913 }
914 }
915 return parameters;
916 }
917
918 TypeProvider get typeProvider {
919 AnalysisContext analysisContext = _context.compilationUnitElement.context;
920 try {
921 return (analysisContext as InternalAnalysisContext).typeProvider;
922 } on AnalysisException catch (exception) {
923 // TODO(brianwilkerson) Figure out the right thing to do if the core canno t be resolved.
924 return null;
925 }
926 }
927
928 bool get hasErrorBeforeCompletionLocation {
929 List<AnalysisError> errors = _context.errors;
930 if (errors == null || errors.length == 0) {
931 return false;
932 }
933 return errors[0].offset <= _completionLocation();
934 }
935
936 List<ImportElement> _importsWithName(SimpleIdentifier libName) {
937 String name = libName.name;
938 List<ImportElement> imports = <ImportElement>[];
939 for (ImportElement imp in currentLibrary.imports) {
940 PrefixElement prefix = imp.prefix;
941 if (prefix != null) {
942 String impName = prefix.displayName;
943 if (name == impName) {
944 imports.add(imp);
945 }
946 }
947 }
948 return imports;
949 }
950
951 bool _isCompletingKeyword(Token keyword) {
952 if (keyword == null) {
953 return false;
954 }
955 int completionLoc = _context.selectionOffset;
956 if (completionLoc >= keyword.offset && completionLoc <= keyword.end) {
957 return true;
958 }
959 return false;
960 }
961
962 bool _isCompletionAfter(int loc) => loc <= _completionLocation();
963
964 bool _isCompletionBefore(int loc) => _completionLocation() <= loc;
965
966 bool _isCompletionBetween(int firstLoc, int secondLoc) => _isCompletionAfter(f irstLoc) && _isCompletionBefore(secondLoc);
967
968 bool _isDeprecated(Element element) => element != null && element.isDeprecated ;
969
970 bool _isInCurrentLibrary(Element element) {
971 LibraryElement libElement = currentLibrary;
972 return identical(element.library, libElement);
973 }
974
975 bool _isUnitInLibFolder(CompilationUnitElement cu) {
976 String pathString = cu.source.fullName;
977 if (pathString.indexOf("/lib/") == -1) {
978 return false;
979 }
980 return true;
981 }
982
983 bool _isVisible(Element element) => !_isPrivate(element) || _isInCurrentLibrar y(element);
984
985 String _makeNonconflictingName(String candidate, List<String> names) {
986 String possibility = candidate;
987 int count = 0;
988 loop: while (true) {
989 String name = count == 0 ? possibility : "${possibility}${count}";
990 for (String conflict in names) {
991 if (name == conflict) {
992 count += 1;
993 continue loop;
994 }
995 }
996 return name;
997 }
998 }
999
1000 void _pArgumentList(CompletionProposal proposal, int offset, int len) {
1001 // prepare parameters
1002 List<String> parameterNames = proposal.parameterNames;
1003 if (parameterNames.length == 0) {
1004 return;
1005 }
1006 // fill arguments proposal
1007 CompletionProposal prop = _createProposal4(CompletionSuggestionKind.ARGUMENT _LIST);
1008 prop.setElement(proposal.element);
1009 prop.setCompletion(proposal.completion).setReturnType(proposal.returnType);
1010 prop.setParameterNames(parameterNames);
1011 prop.setParameterTypes(proposal.parameterTypes);
1012 prop.setParameterStyle(proposal.positionalParameterCount, proposal.hasNamed, proposal.hasPositional);
1013 prop.setReplacementLength(0).setLocation(_completionLocation());
1014 prop.setRelevance(CompletionProposal.RELEVANCE_HIGH);
1015 _requestor.accept(prop);
1016 }
1017
1018 void _pDynamic() {
1019 _pWord(_C_DYNAMIC, CompletionSuggestionKind.LOCAL_VARIABLE);
1020 }
1021
1022 void _pExecutable(Element element, FunctionType functionType, SimpleIdentifier identifier, bool isPotentialMatch) {
1023 // Create a completion proposal for the element: function, method, getter, s etter, constructor.
1024 String name = element.displayName;
1025 if (name.isEmpty) {
1026 return;
1027 }
1028 if (_filterDisallows(element)) {
1029 return;
1030 }
1031 if (!_isVisible(element)) {
1032 return;
1033 }
1034 // May be we are in argument of function type parameter, propose function re ference.
1035 if (_state._targetParameter != null) {
1036 DartType parameterType = _state._targetParameter.type;
1037 if (parameterType is FunctionType) {
1038 if (functionType.isAssignableTo(parameterType)) {
1039 _pName2(name, element, CompletionProposal.RELEVANCE_HIGH, CompletionSu ggestionKind.METHOD_NAME);
1040 }
1041 }
1042 }
1043 CompletionProposal prop = _createProposal(element);
1044 prop.setPotentialMatch(isPotentialMatch);
1045 if (isPotentialMatch) {
1046 prop.setRelevance(CompletionProposal.RELEVANCE_LOW);
1047 }
1048 _setParameterInfo(functionType, prop);
1049 prop.setCompletion(name).setReturnType(functionType.returnType.displayName);
1050 // If there is already argument list, then update only method name.
1051 if (identifier.parent is MethodInvocation && (identifier.parent as MethodInv ocation).argumentList != null) {
1052 prop.setKind(CompletionSuggestionKind.METHOD_NAME);
1053 }
1054 Element container = element.enclosingElement;
1055 if (container != null) {
1056 prop.setDeclaringType(container.displayName);
1057 }
1058 _requestor.accept(prop);
1059 }
1060
1061 void _pExecutable2(ExecutableElement element, SimpleIdentifier identifier, boo l isPotentialMatch) {
1062 _pExecutable(element, element.type, identifier, isPotentialMatch);
1063 }
1064
1065 void _pExecutable3(VariableElement element, SimpleIdentifier identifier) {
1066 // Create a completion proposal for the element: top-level variable.
1067 String name = element.displayName;
1068 if (name.isEmpty || _filterDisallows(element)) {
1069 return;
1070 }
1071 CompletionProposal prop = _createProposal(element);
1072 if (element.type != null) {
1073 prop.setReturnType(element.type.name);
1074 }
1075 Element container = element.enclosingElement;
1076 if (container != null) {
1077 prop.setDeclaringType(container.displayName);
1078 }
1079 if (identifier != null) {
1080 prop.setReplacementLengthIdentifier(identifier.length);
1081 }
1082 _requestor.accept(prop);
1083 }
1084
1085 void _pFalse() {
1086 _pWord(_C_FALSE, CompletionSuggestionKind.LOCAL_VARIABLE);
1087 }
1088
1089 void _pField(FieldElement element, SimpleIdentifier identifier, ClassElement c lassElement) {
1090 // Create a completion proposal for the element: field only.
1091 if (_filterDisallows(element)) {
1092 return;
1093 }
1094 CompletionProposal prop = _createProposal(element);
1095 Element container = element.enclosingElement;
1096 prop.setDeclaringType(container.displayName);
1097 _requestor.accept(prop);
1098 }
1099
1100 /**
1101 * Proposes URI with the given scheme for the given [NamespaceDirective].
1102 */
1103 void _pImportUriWithScheme(NamespaceDirective node, String uriScheme) {
1104 String newUri = "${uriScheme}${new String.fromCharCode(CompletionProposal.CU RSOR_MARKER)}";
1105 if (node.uri.isSynthetic) {
1106 newUri = "'${newUri}'";
1107 if (node.semicolon == null || node.semicolon.isSynthetic) {
1108 newUri += ";";
1109 }
1110 }
1111 if (_context.selectionOffset == node.keyword.end) {
1112 newUri = " ${newUri}";
1113 }
1114 _pName3(newUri, CompletionSuggestionKind.IMPORT);
1115 }
1116
1117 void _pKeyword(Token keyword) {
1118 _filter = new Filter.con2(keyword.lexeme, keyword.offset, _completionLocatio n());
1119 // This isn't as useful as it might seem. It only works in the case that com pletion
1120 // is requested on an existing recognizable keyword.
1121 // TODO: Add keyword proposal kind
1122 CompletionProposal prop = _createProposal4(CompletionSuggestionKind.LIBRARY_ PREFIX);
1123 prop.setCompletion(keyword.lexeme);
1124 _requestor.accept(prop);
1125 }
1126
1127 void _pName(Element element, SimpleIdentifier identifier) {
1128 CompletionProposal prop = _createProposal2(element, identifier);
1129 if (prop != null) {
1130 _requestor.accept(prop);
1131 }
1132 }
1133
1134 void _pName2(String name, Element element, int relevance, CompletionSuggestion Kind kind) {
1135 if (_filterDisallows2(name)) {
1136 return;
1137 }
1138 CompletionProposal prop = _createProposal4(kind);
1139 prop.setRelevance(relevance);
1140 prop.setCompletion(name);
1141 prop.setElement(element);
1142 _requestor.accept(prop);
1143 }
1144
1145 void _pName3(String name, CompletionSuggestionKind kind) {
1146 if (_filterDisallows2(name)) {
1147 return;
1148 }
1149 CompletionProposal prop = _createProposal4(kind);
1150 prop.setCompletion(name);
1151 _requestor.accept(prop);
1152 }
1153
1154 void _pNamedConstructor(ClassElement classElement, ConstructorElement element, SimpleIdentifier identifier) {
1155 // Create a completion proposal for the named constructor.
1156 String name = classElement.displayName;
1157 if (!element.displayName.isEmpty) {
1158 name += ".${element.displayName}";
1159 }
1160 if (_filterDisallows2(name)) {
1161 return;
1162 }
1163 CompletionProposal prop = _createProposal3(element, name);
1164 _setParameterInfo(element.type, prop);
1165 prop.setReturnType(element.type.returnType.name);
1166 Element container = element.enclosingElement;
1167 prop.setDeclaringType(container.displayName);
1168 if (identifier != null) {
1169 prop.setReplacementLengthIdentifier(identifier.length);
1170 }
1171 _requestor.accept(prop);
1172 }
1173
1174 void _pNull() {
1175 _pWord(_C_NULL, CompletionSuggestionKind.LOCAL_VARIABLE);
1176 }
1177
1178 void _pParamName(String name) {
1179 if (_filterDisallows2(name)) {
1180 return;
1181 }
1182 CompletionProposal prop = _createProposal4(CompletionSuggestionKind.PARAMETE R);
1183 prop.setCompletion(name);
1184 _requestor.accept(prop);
1185 }
1186
1187 CompletionSuggestionKind _proposalKindOf(Element element) {
1188 CompletionSuggestionKind kind;
1189 while (true) {
1190 if (element.kind == ElementKind.CONSTRUCTOR) {
1191 kind = CompletionSuggestionKind.CONSTRUCTOR;
1192 } else if (element.kind == ElementKind.FUNCTION) {
1193 kind = CompletionSuggestionKind.FUNCTION;
1194 } else if (element.kind == ElementKind.METHOD) {
1195 kind = CompletionSuggestionKind.METHOD;
1196 } else if (element.kind == ElementKind.GETTER) {
1197 kind = CompletionSuggestionKind.GETTER;
1198 } else if (element.kind == ElementKind.SETTER) {
1199 kind = CompletionSuggestionKind.SETTER;
1200 } else if (element.kind == ElementKind.CLASS) {
1201 kind = CompletionSuggestionKind.CLASS;
1202 } else if (element.kind == ElementKind.FIELD) {
1203 kind = CompletionSuggestionKind.FIELD;
1204 } else if (element.kind == ElementKind.IMPORT) {
1205 kind = CompletionSuggestionKind.IMPORT;
1206 } else if (element.kind == ElementKind.PARAMETER) {
1207 kind = CompletionSuggestionKind.PARAMETER;
1208 } else if (element.kind == ElementKind.PREFIX) {
1209 kind = CompletionSuggestionKind.LIBRARY_PREFIX;
1210 } else if (element.kind == ElementKind.FUNCTION_TYPE_ALIAS) {
1211 kind = CompletionSuggestionKind.CLASS_ALIAS;
1212 } else if (element.kind == ElementKind.TYPE_PARAMETER) {
1213 kind = CompletionSuggestionKind.TYPE_PARAMETER;
1214 } else if (element.kind == ElementKind.LOCAL_VARIABLE || element.kind == E lementKind.TOP_LEVEL_VARIABLE) {
1215 kind = CompletionSuggestionKind.LOCAL_VARIABLE;
1216 } else {
1217 throw new IllegalArgumentException();
1218 }
1219 break;
1220 }
1221 return kind;
1222 }
1223
1224 void _proposeCombinator(Combinator node, SimpleIdentifier identifier) {
1225 _filter = _createFilter(identifier);
1226 NamespaceDirective directive = node.parent as NamespaceDirective;
1227 LibraryElement libraryElement = directive.uriElement;
1228 if (libraryElement != null) {
1229 // prepare Elements with unique names
1230 CompletionEngine_NameCollector nameCollector = _createNameCollector();
1231 Iterable<Element> elements = CorrectionUtils.getExportNamespace2(libraryEl ement).values;
1232 for (Element element in elements) {
1233 if (_filterDisallows(element)) {
1234 continue;
1235 }
1236 nameCollector._mergeName(element);
1237 }
1238 // propose each Element
1239 for (Element element in nameCollector.uniqueElements) {
1240 CompletionProposal proposal = _createProposal(element);
1241 if (proposal.kind == CompletionSuggestionKind.FUNCTION) {
1242 proposal.setKind(CompletionSuggestionKind.METHOD_NAME);
1243 }
1244 _requestor.accept(proposal);
1245 }
1246 }
1247 }
1248
1249 void _proposeName(Element element, SimpleIdentifier identifier, CompletionEngi ne_NameCollector names) {
1250 while (true) {
1251 if (element.kind == ElementKind.FUNCTION || element.kind == ElementKind.GE TTER || element.kind == ElementKind.METHOD || element.kind == ElementKind.SETTER ) {
1252 ExecutableElement candidate = element as ExecutableElement;
1253 _pExecutable2(candidate, identifier, names._isPotentialMatch(candidate)) ;
1254 } else if (element.kind == ElementKind.LOCAL_VARIABLE || element.kind == E lementKind.PARAMETER || element.kind == ElementKind.TOP_LEVEL_VARIABLE) {
1255 FunctionType functionType = _getFunctionType(element);
1256 if (functionType != null) {
1257 _pExecutable(element, functionType, identifier, names._isPotentialMatc h(element));
1258 } else {
1259 VariableElement var2 = element as VariableElement;
1260 _pExecutable3(var2, identifier);
1261 }
1262 } else if (element.kind == ElementKind.CLASS) {
1263 _pName(element, identifier);
1264 } else {
1265 }
1266 break;
1267 }
1268 }
1269
1270 void _proposeNames(CompletionEngine_NameCollector names, SimpleIdentifier iden tifier) {
1271 for (Element element in names.uniqueElements) {
1272 _proposeName(element, identifier, names);
1273 }
1274 }
1275
1276 void _pTrue() {
1277 _pWord(_C_TRUE, CompletionSuggestionKind.LOCAL_VARIABLE);
1278 }
1279
1280 void _pVar() {
1281 _pWord(_C_VAR, CompletionSuggestionKind.LOCAL_VARIABLE);
1282 }
1283
1284 void _pVoid() {
1285 _pWord(_C_VOID, CompletionSuggestionKind.LOCAL_VARIABLE);
1286 }
1287
1288 void _pWord(String word, CompletionSuggestionKind kind) {
1289 if (_filterDisallows2(word)) {
1290 return;
1291 }
1292 CompletionProposal prop = _createProposal4(kind);
1293 prop.setCompletion(word);
1294 _requestor.accept(prop);
1295 }
1296
1297 void _removeNotMatchingFilter(List<Element> elements) {
1298 if (_filter == null) {
1299 return;
1300 }
1301 _filter._makePattern();
1302 _filter._removeNotMatching(elements);
1303 }
1304
1305 void _setParameterInfo(FunctionType functionType, CompletionProposal prop) {
1306 List<String> params = new List<String>();
1307 List<String> types = new List<String>();
1308 bool named = false, positional = false;
1309 int posCount = 0;
1310 for (ParameterElement param in functionType.parameters) {
1311 if (!param.isSynthetic) {
1312 while (true) {
1313 if (param.parameterKind == ParameterKind.REQUIRED) {
1314 posCount += 1;
1315 } else if (param.parameterKind == ParameterKind.NAMED) {
1316 named = true;
1317 } else if (param.parameterKind == ParameterKind.POSITIONAL) {
1318 positional = true;
1319 }
1320 break;
1321 }
1322 params.add(param.displayName);
1323 types.add(param.type.toString());
1324 }
1325 }
1326 prop.setParameterNames(params);
1327 prop.setParameterTypes(types);
1328 prop.setParameterStyle(posCount, named, positional);
1329 }
1330
1331 SimpleIdentifier _typeDeclarationName(AstNode node) {
1332 AstNode parent = node;
1333 while (parent != null) {
1334 if (parent is ClassDeclaration) {
1335 return (parent as ClassDeclaration).name;
1336 }
1337 if (parent is ClassTypeAlias) {
1338 return (parent as ClassTypeAlias).name;
1339 }
1340 if (parent is FunctionTypeAlias) {
1341 return (parent as FunctionTypeAlias).name;
1342 }
1343 parent = parent.parent;
1344 }
1345 return null;
1346 }
1347
1348 DartType _typeOf(Element receiver) {
1349 DartType receiverType;
1350 while (true) {
1351 if (receiver.kind == ElementKind.FIELD || receiver.kind == ElementKind.PAR AMETER || receiver.kind == ElementKind.LOCAL_VARIABLE || receiver.kind == Elemen tKind.TOP_LEVEL_VARIABLE) {
1352 {
1353 VariableElement receiverElement = receiver as VariableElement;
1354 receiverType = receiverElement.type;
1355 break;
1356 }
1357 } else if (receiver.kind == ElementKind.GETTER) {
1358 PropertyAccessorElement accessor = receiver as PropertyAccessorElement;
1359 if (accessor.isSynthetic) {
1360 PropertyInducingElement inducer = accessor.variable;
1361 DartType inducerType = inducer.type;
1362 if (inducerType == null || inducerType.isDynamic) {
1363 receiverType = _typeSearch(inducer);
1364 if (receiverType != null) {
1365 break;
1366 }
1367 }
1368 }
1369 FunctionType accType = accessor.type;
1370 receiverType = accType == null ? null : accType.returnType;
1371 } else if (receiver.kind == ElementKind.CONSTRUCTOR || receiver.kind == El ementKind.FUNCTION || receiver.kind == ElementKind.METHOD || receiver.kind == El ementKind.SETTER) {
1372 {
1373 ExecutableElement receiverElement = receiver as ExecutableElement;
1374 FunctionType funType = receiverElement.type;
1375 receiverType = funType == null ? null : funType.returnType;
1376 break;
1377 }
1378 } else if (receiver.kind == ElementKind.CLASS) {
1379 {
1380 ClassElement receiverElement = receiver as ClassElement;
1381 receiverType = receiverElement.type;
1382 break;
1383 }
1384 } else if (receiver.kind == ElementKind.DYNAMIC) {
1385 {
1386 receiverType = DynamicTypeImpl.instance;
1387 break;
1388 }
1389 } else if (receiver.kind == ElementKind.FUNCTION_TYPE_ALIAS) {
1390 {
1391 FunctionTypeAliasElement receiverElement = receiver as FunctionTypeAli asElement;
1392 FunctionType funType = receiverElement.type;
1393 receiverType = funType == null ? null : funType.returnType;
1394 break;
1395 }
1396 } else {
1397 {
1398 receiverType = null;
1399 break;
1400 }
1401 }
1402 break;
1403 }
1404 return receiverType;
1405 }
1406
1407 DartType _typeOf2(Expression expr) {
1408 DartType type = expr.bestType;
1409 if (type.isDynamic) {
1410 AstNodeClassifier_CompletionEngine_typeOf visitor
1411 = new AstNodeClassifier_CompletionEngine_typeOf(this);
1412 expr.accept(visitor);
1413 DartType result = visitor.result;
1414 if (result != null) {
1415 return result;
1416 }
1417 }
1418 return type;
1419 }
1420
1421 DartType _typeOfContainingClass(AstNode node) {
1422 AstNode parent = node;
1423 while (parent != null) {
1424 if (parent is ClassDeclaration) {
1425 return (parent as ClassDeclaration).element.type;
1426 }
1427 parent = parent.parent;
1428 }
1429 return DynamicTypeImpl.instance;
1430 }
1431
1432 DartType _typeSearch(PropertyInducingElement varElement) {
1433 // TODO(scheglov) translate it
1434 return null;
1435 }
1436 }
1437
1438 abstract class CompletionEngine_AstNodeClassifier extends GeneralizingAstVisitor <Object> {
1439 @override
1440 Object visitNode(AstNode node) => null;
1441 }
1442
1443 class CompletionEngine_CommentReferenceCompleter extends CompletionEngine_AstNod eClassifier {
1444 final CompletionEngine CompletionEngine_this;
1445
1446 final SimpleIdentifier _identifier;
1447
1448 CompletionEngine_NameCollector _names;
1449
1450 Set<Element> _enclosingElements = new Set();
1451
1452 CompletionEngine_CommentReferenceCompleter(this.CompletionEngine_this, this._i dentifier) {
1453 CompletionEngine_this._filter = CompletionEngine_this._createFilter(_identif ier);
1454 _names = CompletionEngine_this._collectTopLevelElementVisibleAt(_identifier) ;
1455 }
1456
1457 @override
1458 Object visitClassDeclaration(ClassDeclaration node) {
1459 ClassElement classElement = node.element;
1460 _names._addNamesDefinedByHierarchy(classElement, false);
1461 _enclosingElements.add(classElement);
1462 return null;
1463 }
1464
1465 @override
1466 Object visitComment(Comment node) {
1467 node.parent.accept(this);
1468 // propose names
1469 for (Element element in _names.uniqueElements) {
1470 CompletionProposal proposal = CompletionEngine_this._createProposal2(eleme nt, _identifier);
1471 if (proposal != null) {
1472 // we don't want to add arguments, just names
1473 if (element is MethodElement || element is FunctionElement) {
1474 proposal.setKind(CompletionSuggestionKind.METHOD_NAME);
1475 }
1476 // elevate priority for local elements
1477 if (_enclosingElements.contains(element.enclosingElement)) {
1478 proposal.setRelevance(CompletionProposal.RELEVANCE_HIGH);
1479 }
1480 // propose
1481 CompletionEngine_this._requestor.accept(proposal);
1482 }
1483 }
1484 // done
1485 return null;
1486 }
1487
1488 @override
1489 Object visitConstructorDeclaration(ConstructorDeclaration node) {
1490 _visitExecutableDeclaration(node);
1491 // pass through
1492 return node.parent.accept(this);
1493 }
1494
1495 @override
1496 Object visitFunctionDeclaration(FunctionDeclaration node) {
1497 _visitExecutableDeclaration(node);
1498 return null;
1499 }
1500
1501 @override
1502 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
1503 FunctionTypeAliasElement element = node.element;
1504 _names._mergeNames(element.parameters);
1505 _enclosingElements.add(element);
1506 return null;
1507 }
1508
1509 @override
1510 Object visitMethodDeclaration(MethodDeclaration node) {
1511 _visitExecutableDeclaration(node);
1512 // pass through
1513 return node.parent.accept(this);
1514 }
1515
1516 void _visitExecutableDeclaration(Declaration node) {
1517 ExecutableElement element = node.element as ExecutableElement;
1518 _names._mergeNames(element.parameters);
1519 _enclosingElements.add(element);
1520 }
1521 }
1522
1523 /**
1524 * An IdentifierCompleter is used to classify the parent of the completion node when it has
1525 * previously been determined that the completion node is a SimpleIdentifier.
1526 */
1527 class CompletionEngine_IdentifierCompleter extends CompletionEngine_AstNodeClass ifier {
1528 final CompletionEngine CompletionEngine_this;
1529
1530 SimpleIdentifier _completionNode;
1531
1532 CompletionEngine_IdentifierCompleter(this.CompletionEngine_this, SimpleIdentif ier node) {
1533 _completionNode = node;
1534 }
1535
1536 @override
1537 Object visitAnnotation(Annotation node) {
1538 if (_completionNode is SimpleIdentifier) {
1539 CompletionEngine_this._analyzeAnnotationName(_completionNode);
1540 }
1541 return null;
1542 }
1543
1544 @override
1545 Object visitArgumentList(ArgumentList node) {
1546 if (_completionNode is SimpleIdentifier) {
1547 if (CompletionEngine_this._isCompletionBetween(node.leftParenthesis.end, n ode.rightParenthesis.offset)) {
1548 CompletionEngine_this._analyzeLocalName(_completionNode);
1549 CompletionEngine_this._analyzePositionalArgument(node, _completionNode);
1550 CompletionEngine_this._analyzeNamedParameter(node, _completionNode);
1551 }
1552 }
1553 return null;
1554 }
1555
1556 @override
1557 Object visitAssignmentExpression(AssignmentExpression node) {
1558 if (_completionNode is SimpleIdentifier) {
1559 CompletionEngine_this._analyzeLocalName(_completionNode);
1560 }
1561 return null;
1562 }
1563
1564 @override
1565 Object visitBinaryExpression(BinaryExpression node) {
1566 if (identical(node.leftOperand, _completionNode)) {
1567 CompletionEngine_this._analyzeLocalName(_completionNode);
1568 } else if (identical(node.rightOperand, _completionNode)) {
1569 CompletionEngine_this._analyzeLocalName(_completionNode);
1570 }
1571 return null;
1572 }
1573
1574 @override
1575 Object visitCombinator(Combinator node) {
1576 CompletionEngine_this._proposeCombinator(node, _completionNode);
1577 return null;
1578 }
1579
1580 @override
1581 Object visitCommentReference(CommentReference node) {
1582 AstNode comment = node.parent;
1583 CompletionEngine_CommentReferenceCompleter visitor = new CompletionEngine_Co mmentReferenceCompleter(CompletionEngine_this, _completionNode);
1584 return comment.accept(visitor);
1585 }
1586
1587 @override
1588 Object visitConstructorDeclaration(ConstructorDeclaration node) {
1589 if (identical(node.returnType, _completionNode)) {
1590 CompletionEngine_this._filter = CompletionEngine_this._createFilter(_compl etionNode);
1591 CompletionEngine_this._pName3(_completionNode.name, CompletionSuggestionKi nd.CONSTRUCTOR);
1592 }
1593 return null;
1594 }
1595
1596 @override
1597 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
1598 // { A() : this.!x = 1; }
1599 if (identical(node.fieldName, _completionNode)) {
1600 ClassElement classElement = (node.parent as ConstructorDeclaration).elemen t.enclosingElement;
1601 CompletionEngine_this._fieldReference(classElement, node.fieldName);
1602 }
1603 return null;
1604 }
1605
1606 @override
1607 Object visitConstructorName(ConstructorName node) {
1608 if (identical(node.name, _completionNode)) {
1609 // { new A.!c(); }
1610 TypeName typeName = node.type;
1611 if (typeName != null) {
1612 DartType type = typeName.type;
1613 Element typeElement = type.element;
1614 if (typeElement is ClassElement) {
1615 ClassElement classElement = typeElement;
1616 CompletionEngine_this._constructorReference(classElement, node.name);
1617 }
1618 }
1619 }
1620 return null;
1621 }
1622
1623 @override
1624 Object visitDoStatement(DoStatement node) {
1625 if (identical(node.condition, _completionNode)) {
1626 CompletionEngine_this._analyzeLocalName(_completionNode);
1627 }
1628 return null;
1629 }
1630
1631 @override
1632 Object visitExpression(Expression node) {
1633 SimpleIdentifier ident;
1634 if (_completionNode is SimpleIdentifier) {
1635 ident = _completionNode;
1636 } else {
1637 ident = CompletionEngine_this._createIdent(node);
1638 }
1639 CompletionEngine_this._analyzeLocalName(ident);
1640 return null;
1641 }
1642
1643 @override
1644 Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
1645 if (identical(_completionNode, node.expression)) {
1646 CompletionEngine_this._analyzeLocalName(_completionNode);
1647 }
1648 return null;
1649 }
1650
1651 @override
1652 Object visitExpressionStatement(ExpressionStatement node) {
1653 SimpleIdentifier ident;
1654 if (_completionNode is SimpleIdentifier) {
1655 ident = _completionNode;
1656 } else {
1657 ident = CompletionEngine_this._createIdent(node);
1658 }
1659 CompletionEngine_this._analyzeLocalName(ident);
1660 return null;
1661 }
1662
1663 @override
1664 Object visitFieldFormalParameter(FieldFormalParameter node) {
1665 if (identical(_completionNode, node.identifier)) {
1666 CompletionEngine_this._analyzeImmediateField(node.identifier);
1667 }
1668 return null;
1669 }
1670
1671 @override
1672 Object visitForEachStatement(ForEachStatement node) {
1673 if (identical(node.iterator, _completionNode)) {
1674 CompletionEngine_this._analyzeLocalName(_completionNode);
1675 }
1676 return null;
1677 }
1678
1679 @override
1680 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
1681 if (identical(node.name, _completionNode)) {
1682 if (node.returnType == null) {
1683 // This may be an incomplete class type alias
1684 CompletionEngine_this._state._includesUndefinedTypes();
1685 CompletionEngine_this._analyzeTypeName(node.name, CompletionEngine_this. _typeDeclarationName(node));
1686 }
1687 }
1688 return null;
1689 }
1690
1691 @override
1692 Object visitIfStatement(IfStatement node) {
1693 if (identical(node.condition, _completionNode)) {
1694 // { if (!) }
1695 CompletionEngine_this._analyzeLocalName(new Ident.con3(node, _completionNo de.token));
1696 }
1697 return null;
1698 }
1699
1700 @override
1701 Object visitInterpolationExpression(InterpolationExpression node) {
1702 if (node.expression is SimpleIdentifier) {
1703 SimpleIdentifier ident = node.expression as SimpleIdentifier;
1704 CompletionEngine_this._analyzeLocalName(ident);
1705 }
1706 return null;
1707 }
1708
1709 @override
1710 Object visitLibraryIdentifier(LibraryIdentifier node) => null;
1711
1712 @override
1713 Object visitMethodDeclaration(MethodDeclaration node) {
1714 if (identical(_completionNode, node.name)) {
1715 if (node.returnType == null) {
1716 // class Foo {const F!(); }
1717 CompletionEngine_this._analyzeLocalName(_completionNode);
1718 }
1719 }
1720 return null;
1721 }
1722
1723 @override
1724 Object visitMethodInvocation(MethodInvocation node) {
1725 if (identical(node.methodName, _completionNode)) {
1726 // { x.!y() }
1727 Expression expr = node.realTarget;
1728 DartType receiverType;
1729 if (expr == null) {
1730 receiverType = CompletionEngine_this._typeOfContainingClass(node);
1731 CompletionEngine_this._analyzeDirectAccess(receiverType, node.methodName );
1732 } else {
1733 CompletionEngine_this._dispatchPrefixAnalysis2(node);
1734 }
1735 } else if (identical(node.target, _completionNode)) {
1736 // { x!.y() } -- only reached when node.getTarget() is a simple identifier .
1737 if (_completionNode is SimpleIdentifier) {
1738 SimpleIdentifier ident = _completionNode;
1739 CompletionEngine_this._analyzeReceiver(ident);
1740 }
1741 }
1742 return null;
1743 }
1744
1745 @override
1746 Object visitParenthesizedExpression(ParenthesizedExpression node) {
1747 // Incomplete closure: foo((Str!)); We check if "()" is argument for functio n typed parameter.
1748 if (node.parent is ArgumentList) {
1749 ParameterElement parameterElement = node.bestParameterElement;
1750 if (parameterElement != null && parameterElement.type is FunctionType) {
1751 Ident ident = CompletionEngine_this._createIdent(_completionNode);
1752 CompletionEngine_this._analyzeTypeName(_completionNode, ident);
1753 }
1754 }
1755 return super.visitParenthesizedExpression(node);
1756 }
1757
1758 @override
1759 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
1760 if (identical(node.prefix, _completionNode)) {
1761 // { x!.y }
1762 CompletionEngine_this._analyzeLocalName(node.prefix);
1763 } else {
1764 // { v.! }
1765 CompletionEngine_this._dispatchPrefixAnalysis3(node, node.identifier);
1766 }
1767 return null;
1768 }
1769
1770 @override
1771 Object visitPropertyAccess(PropertyAccess node) {
1772 if (node.target != null && node.target.length == 0) {
1773 return null;
1774 }
1775 // { o.!hashCode }
1776 if (identical(node.propertyName, _completionNode)) {
1777 CompletionEngine_this._analyzePrefixedAccess(node.realTarget, node.propert yName);
1778 }
1779 return null;
1780 }
1781
1782 @override
1783 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
1784 // { A.Fac() : this.!b(); }
1785 if (identical(node.constructorName, _completionNode)) {
1786 ClassElement classElement = node.staticElement.enclosingElement;
1787 CompletionEngine_this._constructorReference(classElement, node.constructor Name);
1788 }
1789 return null;
1790 }
1791
1792 @override
1793 Object visitReturnStatement(ReturnStatement node) {
1794 if (_completionNode is SimpleIdentifier) {
1795 CompletionEngine_this._analyzeLocalName(_completionNode);
1796 }
1797 return null;
1798 }
1799
1800 @override
1801 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
1802 if (identical(node.identifier, _completionNode)) {
1803 if (node.keyword == null && node.type == null) {
1804 Ident ident = CompletionEngine_this._createIdent(node);
1805 CompletionEngine_this._analyzeTypeName(node.identifier, ident);
1806 }
1807 }
1808 return null;
1809 }
1810
1811 @override
1812 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
1813 CompletionEngine_this._analyzeSuperConstructorInvocation(node);
1814 return null;
1815 }
1816
1817 @override
1818 Object visitSwitchCase(SwitchCase node) {
1819 if (identical(_completionNode, node.expression)) {
1820 CompletionEngine_this._analyzeLocalName(_completionNode);
1821 }
1822 return null;
1823 }
1824
1825 @override
1826 Object visitSwitchStatement(SwitchStatement node) {
1827 if (identical(node.expression, _completionNode)) {
1828 CompletionEngine_this._analyzeLocalName(_completionNode);
1829 }
1830 return null;
1831 }
1832
1833 @override
1834 Object visitTypeName(TypeName node) {
1835 AstNode parent = node.parent;
1836 if (parent != null) {
1837 CompletionEngine_TypeNameCompleter visitor = new CompletionEngine_TypeName Completer(CompletionEngine_this, _completionNode, node);
1838 return parent.accept(visitor);
1839 }
1840 return null;
1841 }
1842
1843 @override
1844 Object visitTypeParameter(TypeParameter node) {
1845 // { X<!Y> }
1846 if (CompletionEngine_this._isCompletionBetween(node.offset, node.end)) {
1847 CompletionEngine_this._analyzeTypeName(_completionNode, CompletionEngine_t his._typeDeclarationName(node));
1848 }
1849 return null;
1850 }
1851
1852 @override
1853 Object visitVariableDeclaration(VariableDeclaration node) {
1854 if (identical(node.name, _completionNode)) {
1855 CompletionEngine_this._analyzeDeclarationName(node);
1856 } else if (identical(node.initializer, _completionNode)) {
1857 CompletionEngine_this._analyzeLocalName(node.initializer as SimpleIdentifi er);
1858 }
1859 return null;
1860 }
1861
1862 @override
1863 Object visitWhileStatement(WhileStatement node) {
1864 if (identical(node.condition, _completionNode)) {
1865 CompletionEngine_this._analyzeLocalName(_completionNode);
1866 }
1867 return null;
1868 }
1869 }
1870
1871 class CompletionEngine_NameCollector {
1872 final CompletionEngine CompletionEngine_this;
1873
1874 Map<String, List<Element>> _uniqueNames = new Map<String, List<Element>>();
1875
1876 Set<Element> _potentialMatches;
1877
1878 CompletionEngine_NameCollector(this.CompletionEngine_this);
1879
1880 void addAll(Iterable<SimpleIdentifier> values) {
1881 for (SimpleIdentifier id in values) {
1882 _mergeName(id.bestElement);
1883 }
1884 }
1885
1886 void addLocalNames(SimpleIdentifier identifier) {
1887 AstNode node = identifier;
1888 Declaration decl;
1889 while ((decl = node.getAncestor((node) => node is Declaration)) != null) {
1890 Element declElement = decl.element;
1891 if (declElement is ExecutableElement) {
1892 _addNamesDefinedByExecutable(declElement);
1893 } else {
1894 return;
1895 }
1896 node = decl.parent;
1897 }
1898 }
1899
1900 void _addNamesDefinedByExecutable(ExecutableElement execElement) {
1901 _mergeNames(execElement.parameters);
1902 _mergeNames(execElement.localVariables);
1903 _mergeNames(execElement.functions);
1904 }
1905
1906 void _addNamesDefinedByHierarchy(ClassElement classElement, bool forSuper) {
1907 _addNamesDefinedByHierarchy2(classElement.type, forSuper);
1908 }
1909
1910 void _addNamesDefinedByHierarchy2(InterfaceType type, bool forSuper) {
1911 List<InterfaceType> superTypes = type.element.allSupertypes;
1912 if (!forSuper) {
1913 superTypes.insert(0, type);
1914 }
1915 _addNamesDefinedByTypes(superTypes);
1916 // Collect names defined by subtypes separately so they can be identified la ter.
1917 CompletionEngine_NameCollector potentialMatchCollector = CompletionEngine_th is._createNameCollector();
1918 if (!type.isObject) {
1919 potentialMatchCollector._addNamesDefinedByTypes(CompletionEngine_this._all Subtypes(type.element));
1920 }
1921 _potentialMatches = new Set<Element>();
1922 for (List<Element> matches in potentialMatchCollector._uniqueNames.values) {
1923 for (Element match in matches) {
1924 _mergeName(match);
1925 _potentialMatches.add(match);
1926 }
1927 }
1928 }
1929
1930 void _addNamesDefinedByType(ClassElement classElement) {
1931 _addNamesDefinedByType2(classElement.type);
1932 }
1933
1934 void _addNamesDefinedByType2(InterfaceType type) {
1935 if (_inPrivateLibrary(type)) {
1936 return;
1937 }
1938 List<PropertyAccessorElement> accessors = type.accessors;
1939 _mergeNames(accessors);
1940 List<MethodElement> methods = type.methods;
1941 _mergeNames(methods);
1942 _mergeNames(type.element.typeParameters);
1943 _filterStaticRefs(accessors);
1944 _filterStaticRefs(methods);
1945 }
1946
1947 void _addNamesDefinedByTypes(List<InterfaceType> types) {
1948 for (InterfaceType type in types) {
1949 _addNamesDefinedByType2(type);
1950 }
1951 }
1952
1953 void _addTopLevelNames(List<ImportElement> imports, TopLevelNamesKind topKind) {
1954 for (ImportElement imp in imports) {
1955 Iterable<Element> elementsCollection = CorrectionUtils.getImportNamespace( imp).values;
1956 List<Element> elements = [];
1957 _addTopLevelNames4(elements);
1958 }
1959 }
1960
1961 void _addTopLevelNames2(LibraryElement library, TopLevelNamesKind topKind) {
1962 List<Element> elements = CompletionEngine_this._findTopLevelElements(library , topKind);
1963 _addTopLevelNames4(elements);
1964 }
1965
1966 void _addTopLevelNames3(List<LibraryElement> libraries, TopLevelNamesKind topK ind) {
1967 for (LibraryElement library in libraries) {
1968 _addTopLevelNames2(library, topKind);
1969 }
1970 }
1971
1972 Iterable<List<Element>> get names => _uniqueNames.values;
1973
1974 Iterable<Element> get uniqueElements {
1975 List<Element> uniqueElements = [];
1976 for (List<Element> uniques in _uniqueNames.values) {
1977 Element element = uniques[0];
1978 uniqueElements.add(element);
1979 }
1980 return uniqueElements;
1981 }
1982
1983 bool _isPotentialMatch(Element element) => _potentialMatches != null && _poten tialMatches.contains(element);
1984
1985 void _remove(Element element) {
1986 String name = element.displayName;
1987 List<Element> list = _uniqueNames[name];
1988 if (list == null) {
1989 return;
1990 }
1991 list.remove(element);
1992 if (list.isEmpty) {
1993 _uniqueNames.remove(name);
1994 }
1995 }
1996
1997 void _addTopLevelNames4(List<Element> elements) {
1998 _mergeNames(CompletionEngine_this._findAllTypes2(elements));
1999 if (!CompletionEngine_this._state._areClassesRequired) {
2000 _mergeNames(CompletionEngine_this._findAllNotTypes(elements));
2001 _mergeNames(CompletionEngine_this._findAllPrefixes());
2002 }
2003 }
2004
2005 void _filterStaticRefs(List<ExecutableElement> elements) {
2006 for (ExecutableElement execElem in elements) {
2007 if (CompletionEngine_this._state._areInstanceReferencesProhibited && !exec Elem.isStatic) {
2008 _remove(execElem);
2009 } else if (CompletionEngine_this._state._areStaticReferencesProhibited && execElem.isStatic) {
2010 _remove(execElem);
2011 } else if (!CompletionEngine_this._state._areOperatorsAllowed && execElem. isOperator) {
2012 _remove(execElem);
2013 } else if (CompletionEngine_this._state._areMethodsProhibited && !execElem .isOperator) {
2014 _remove(execElem);
2015 }
2016 }
2017 }
2018
2019 bool _inPrivateLibrary(InterfaceType type) {
2020 LibraryElement lib = type.element.library;
2021 if (!lib.name.startsWith("_")) {
2022 return false;
2023 }
2024 // allow completion in the same library
2025 if (identical(lib, CompletionEngine_this.currentLibrary)) {
2026 return false;
2027 }
2028 // eliminate types defined in private libraries
2029 return true;
2030 }
2031
2032 void _mergeName(Element element) {
2033 if (element == null) {
2034 return;
2035 }
2036 // ignore private
2037 String name = element.displayName;
2038 if (Identifier.isPrivateName(name)) {
2039 if (!CompletionEngine_this._isInCurrentLibrary(element)) {
2040 return;
2041 }
2042 }
2043 // add to other Element(s) with such name
2044 List<Element> dups = _uniqueNames[name];
2045 if (dups == null) {
2046 dups = new List<Element>();
2047 _uniqueNames[name] = dups;
2048 }
2049 dups.add(element);
2050 }
2051
2052 void _mergeNames(List<Element> elements) {
2053 for (Element element in elements) {
2054 _mergeName(element);
2055 }
2056 }
2057 }
2058
2059 /**
2060 * An StringCompleter is used to classify the parent of the completion node when it has previously
2061 * been determined that the completion node is a SimpleStringLiteral.
2062 */
2063 class CompletionEngine_StringCompleter extends CompletionEngine_AstNodeClassifie r {
2064 final CompletionEngine CompletionEngine_this;
2065
2066 SimpleStringLiteral _completionNode;
2067
2068 CompletionEngine_StringCompleter(this.CompletionEngine_this, SimpleStringLiter al node) {
2069 _completionNode = node;
2070 }
2071
2072 @override
2073 Object visitNamespaceDirective(NamespaceDirective node) {
2074 if (identical(_completionNode, node.uri)) {
2075 CompletionEngine_this._namespaceReference(node, _completionNode);
2076 }
2077 return null;
2078 }
2079 }
2080
2081 /**
2082 * A TerminalNodeCompleter is used to classify the completion node when nothing else is known
2083 * about it.
2084 */
2085 class CompletionEngine_TerminalNodeCompleter extends CompletionEngine_AstNodeCla ssifier {
2086 final CompletionEngine CompletionEngine_this;
2087
2088 CompletionEngine_TerminalNodeCompleter(this.CompletionEngine_this);
2089
2090 @override
2091 Object visitArgumentList(ArgumentList node) {
2092 if (node.arguments.isEmpty && CompletionEngine_this._isCompletionBetween(nod e.leftParenthesis.end, node.rightParenthesis.offset)) {
2093 if (node.parent is MethodInvocation) {
2094 // or node.getParent().accept(this); ?
2095 MethodInvocation invokeNode = node.parent as MethodInvocation;
2096 SimpleIdentifier methodName = invokeNode.methodName;
2097 ProposalCollector proposalRequestor = new ProposalCollector(CompletionEn gine_this._requestor);
2098 try {
2099 CompletionEngine_this._requestor = proposalRequestor;
2100 CompletionEngine_this._dispatchPrefixAnalysis2(invokeNode);
2101 } finally {
2102 CompletionEngine_this._requestor = proposalRequestor.requestor;
2103 }
2104 int offset = methodName.offset;
2105 int len = node.rightParenthesis.end - offset;
2106 String name = methodName.name;
2107 for (CompletionProposal proposal in proposalRequestor.proposals) {
2108 if (proposal.completion == name) {
2109 CompletionEngine_this._pArgumentList(proposal, offset, len);
2110 }
2111 }
2112 } else if (node.parent is InstanceCreationExpression) {
2113 InstanceCreationExpression invokeNode = node.parent as InstanceCreationE xpression;
2114 ConstructorName methodName = invokeNode.constructorName;
2115 ProposalCollector proposalRequestor = new ProposalCollector(CompletionEn gine_this._requestor);
2116 try {
2117 CompletionEngine_this._requestor = proposalRequestor;
2118 CompletionEngine_this._dispatchPrefixAnalysis(invokeNode);
2119 } finally {
2120 CompletionEngine_this._requestor = proposalRequestor.requestor;
2121 }
2122 int offset = methodName.offset;
2123 int len = node.rightParenthesis.end - offset;
2124 for (CompletionProposal proposal in proposalRequestor.proposals) {
2125 if (proposal.element == invokeNode.staticElement) {
2126 CompletionEngine_this._pArgumentList(proposal, offset, len);
2127 }
2128 }
2129 } else if (node.parent is Annotation) {
2130 Annotation annotation = node.parent as Annotation;
2131 Element annotationElement = annotation.element;
2132 if (annotationElement is ConstructorElement) {
2133 ConstructorElement constructorElement = annotationElement;
2134 // we don't need any filter
2135 CompletionEngine_this._filter = new Filter.con2("", -1, 0);
2136 // fill parameters for "pArgumentList"
2137 CompletionProposal prop = CompletionEngine_this._createProposal(constr uctorElement);
2138 CompletionEngine_this._setParameterInfo(constructorElement.type, prop) ;
2139 prop.setCompletion(constructorElement.enclosingElement.name);
2140 // propose the whole parameters list
2141 CompletionEngine_this._pArgumentList(prop, 0, 0);
2142 }
2143 }
2144 }
2145 if (CompletionEngine_this._isCompletionBetween(node.leftParenthesis.end, nod e.rightParenthesis.offset)) {
2146 Ident ident = CompletionEngine_this._createIdent(node);
2147 CompletionEngine_this._analyzeLocalName(ident);
2148 CompletionEngine_this._analyzePositionalArgument(node, ident);
2149 CompletionEngine_this._analyzeNamedParameter(node, ident);
2150 }
2151 return null;
2152 }
2153
2154 @override
2155 Object visitAsExpression(AsExpression node) {
2156 if (CompletionEngine_this._isCompletionAfter(node.asOperator.end)) {
2157 CompletionEngine_this._state._isDynamicAllowed = false;
2158 CompletionEngine_this._state._isVoidAllowed = false;
2159 CompletionEngine_this._analyzeTypeName(CompletionEngine_this._createIdent( node), null);
2160 }
2161 return null;
2162 }
2163
2164 @override
2165 Object visitAssertStatement(AssertStatement node) {
2166 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2167 CompletionEngine_this._pKeyword(node.keyword);
2168 }
2169 return null;
2170 }
2171
2172 @override
2173 Object visitBlock(Block node) {
2174 if (CompletionEngine_this._isCompletionBetween(node.leftBracket.end, node.ri ghtBracket.offset)) {
2175 // { {! stmt; !} }
2176 CompletionEngine_this._analyzeLocalName(CompletionEngine_this._createIdent (node));
2177 }
2178 return null;
2179 }
2180
2181 @override
2182 Object visitBooleanLiteral(BooleanLiteral node) {
2183 CompletionEngine_this._analyzeLiteralReference(node);
2184 return null;
2185 }
2186
2187 @override
2188 Object visitBreakStatement(BreakStatement node) {
2189 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2190 CompletionEngine_this._pKeyword(node.keyword);
2191 }
2192 return null;
2193 }
2194
2195 @override
2196 Object visitCatchClause(CatchClause node) {
2197 if (CompletionEngine_this._isCompletingKeyword(node.onKeyword)) {
2198 CompletionEngine_this._pKeyword(node.onKeyword);
2199 } else if (CompletionEngine_this._isCompletingKeyword(node.catchKeyword)) {
2200 CompletionEngine_this._pKeyword(node.catchKeyword);
2201 }
2202 return null;
2203 }
2204
2205 @override
2206 Object visitClassDeclaration(ClassDeclaration node) {
2207 if (CompletionEngine_this._isCompletingKeyword(node.classKeyword)) {
2208 CompletionEngine_this._pKeyword(node.classKeyword);
2209 } else if (CompletionEngine_this._isCompletingKeyword(node.abstractKeyword)) {
2210 CompletionEngine_this._pKeyword(node.abstractKeyword);
2211 } else if (!node.leftBracket.isSynthetic) {
2212 if (CompletionEngine_this._isCompletionAfter(node.leftBracket.end)) {
2213 if (node.rightBracket.isSynthetic || CompletionEngine_this._isCompletion Before(node.rightBracket.offset)) {
2214 if (!CompletionEngine_this.hasErrorBeforeCompletionLocation) {
2215 CompletionEngine_this._analyzeLocalName(CompletionEngine_this._creat eIdent(node));
2216 }
2217 }
2218 }
2219 }
2220 // TODO { abstract ! class ! A ! extends B implements C, D ! {}}
2221 return null;
2222 }
2223
2224 @override
2225 Object visitClassTypeAlias(ClassTypeAlias node) {
2226 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2227 CompletionEngine_this._pKeyword(node.keyword);
2228 }
2229 // TODO { typedef ! A ! = ! B ! with C, D !; }
2230 return null;
2231 }
2232
2233 @override
2234 Object visitCombinator(Combinator node) {
2235 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2236 CompletionEngine_this._pKeyword(node.keyword);
2237 }
2238 return null;
2239 }
2240
2241 @override
2242 Object visitCompilationUnit(CompilationUnit node) => null;
2243
2244 @override
2245 Object visitConstructorName(ConstructorName node) {
2246 // { new A.!c(); }
2247 TypeName typeName = node.type;
2248 if (typeName != null) {
2249 DartType type = typeName.type;
2250 Element typeElement = type.element;
2251 if (typeElement is ClassElement) {
2252 ClassElement classElement = typeElement;
2253 CompletionEngine_this._constructorReference(classElement, node.name);
2254 }
2255 }
2256 return null;
2257 }
2258
2259 @override
2260 Object visitContinueStatement(ContinueStatement node) {
2261 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2262 CompletionEngine_this._pKeyword(node.keyword);
2263 }
2264 return null;
2265 }
2266
2267 @override
2268 Object visitDirective(Directive node) {
2269 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2270 CompletionEngine_this._pKeyword(node.keyword);
2271 }
2272 return null;
2273 }
2274
2275 @override
2276 Object visitDoStatement(DoStatement node) {
2277 if (CompletionEngine_this._isCompletingKeyword(node.doKeyword)) {
2278 CompletionEngine_this._pKeyword(node.doKeyword);
2279 } else if (CompletionEngine_this._isCompletingKeyword(node.whileKeyword)) {
2280 CompletionEngine_this._pKeyword(node.whileKeyword);
2281 } else if (CompletionEngine_this._isCompletionBetween(node.condition.end, no de.rightParenthesis.offset)) {
2282 CompletionEngine_this._operatorAccess(node.condition, CompletionEngine_thi s._createIdent(node));
2283 }
2284 return null;
2285 }
2286
2287 @override
2288 Object visitDoubleLiteral(DoubleLiteral node) => null;
2289
2290 @override
2291 Object visitExportDirective(ExportDirective node) {
2292 visitNamespaceDirective(node);
2293 return null;
2294 }
2295
2296 @override
2297 Object visitExpression(Expression node) {
2298 CompletionEngine_this._analyzeLocalName(CompletionEngine_this._createIdent(n ode));
2299 return null;
2300 }
2301
2302 @override
2303 Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
2304 if (node.expression != null && node.semicolon != null) {
2305 if (CompletionEngine_this._isCompletionBetween(node.expression.end, node.s emicolon.offset)) {
2306 CompletionEngine_this._operatorAccess(node.expression, CompletionEngine_ this._createIdent(node));
2307 }
2308 }
2309 return null;
2310 }
2311
2312 @override
2313 Object visitExpressionStatement(ExpressionStatement node) {
2314 CompletionEngine_this._analyzeLocalName(CompletionEngine_this._createIdent(n ode));
2315 return null;
2316 }
2317
2318 @override
2319 Object visitExtendsClause(ExtendsClause node) {
2320 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2321 CompletionEngine_this._pKeyword(node.keyword);
2322 } else if (node.superclass == null) {
2323 // { X extends ! }
2324 CompletionEngine_this._analyzeTypeName(CompletionEngine_this._createIdent( node), CompletionEngine_this._typeDeclarationName(node));
2325 } else {
2326 // { X extends ! Y }
2327 CompletionEngine_this._analyzeTypeName(CompletionEngine_this._createIdent( node), CompletionEngine_this._typeDeclarationName(node));
2328 }
2329 return null;
2330 }
2331
2332 @override
2333 Object visitForEachStatement(ForEachStatement node) {
2334 if (CompletionEngine_this._isCompletingKeyword(node.forKeyword)) {
2335 CompletionEngine_this._pKeyword(node.forKeyword);
2336 } else if (CompletionEngine_this._isCompletingKeyword(node.inKeyword)) {
2337 CompletionEngine_this._pKeyword(node.inKeyword);
2338 }
2339 return null;
2340 }
2341
2342 @override
2343 Object visitFormalParameterList(FormalParameterList node) {
2344 if (CompletionEngine_this._isCompletionBetween(node.leftParenthesis.end, nod e.rightParenthesis.offset)) {
2345 NodeList<FormalParameter> params = node.parameters;
2346 if (!params.isEmpty) {
2347 FormalParameter last = params[params.length - 1];
2348 if (CompletionEngine_this._isCompletionBetween(last.end, node.rightParen thesis.offset)) {
2349 List<FormalParameter> newParams = CompletionEngine_this._copyWithout(p arams, last);
2350 CompletionEngine_this._analyzeNewParameterName(newParams, last.identif ier, null);
2351 } else {
2352 Ident ident = CompletionEngine_this._createIdent(node);
2353 CompletionEngine_this._analyzeTypeName(ident, ident);
2354 }
2355 } else {
2356 Ident ident = CompletionEngine_this._createIdent(node);
2357 CompletionEngine_this._analyzeTypeName(ident, ident);
2358 }
2359 }
2360 return null;
2361 }
2362
2363 @override
2364 Object visitForStatement(ForStatement node) {
2365 if (CompletionEngine_this._isCompletingKeyword(node.forKeyword)) {
2366 CompletionEngine_this._pKeyword(node.forKeyword);
2367 }
2368 return null;
2369 }
2370
2371 @override
2372 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
2373 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2374 CompletionEngine_this._pKeyword(node.keyword);
2375 }
2376 return null;
2377 }
2378
2379 @override
2380 Object visitIfStatement(IfStatement node) {
2381 if (CompletionEngine_this._isCompletingKeyword(node.ifKeyword)) {
2382 CompletionEngine_this._pKeyword(node.ifKeyword);
2383 } else if (CompletionEngine_this._isCompletingKeyword(node.elseKeyword)) {
2384 CompletionEngine_this._pKeyword(node.elseKeyword);
2385 } else if (CompletionEngine_this._isCompletionBetween(node.condition.end, no de.rightParenthesis.offset)) {
2386 CompletionEngine_this._operatorAccess(node.condition, CompletionEngine_thi s._createIdent(node));
2387 }
2388 return null;
2389 }
2390
2391 @override
2392 Object visitImplementsClause(ImplementsClause node) {
2393 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2394 CompletionEngine_this._pKeyword(node.keyword);
2395 } else if (node.interfaces.isEmpty) {
2396 // { X implements ! }
2397 CompletionEngine_this._analyzeTypeName(CompletionEngine_this._createIdent( node), CompletionEngine_this._typeDeclarationName(node));
2398 } else {
2399 // { X implements ! Y }
2400 CompletionEngine_this._analyzeTypeName(CompletionEngine_this._createIdent( node), CompletionEngine_this._typeDeclarationName(node));
2401 }
2402 return null;
2403 }
2404
2405 @override
2406 Object visitImportDirective(ImportDirective node) {
2407 if (CompletionEngine_this._isCompletingKeyword(node.asToken)) {
2408 CompletionEngine_this._pKeyword(node.asToken);
2409 } else {
2410 visitNamespaceDirective(node);
2411 }
2412 return null;
2413 }
2414
2415 @override
2416 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
2417 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2418 CompletionEngine_this._pKeyword(node.keyword);
2419 Ident ident = new Ident.con3(node, node.keyword);
2420 CompletionEngine_this._analyzeLocalName(ident);
2421 } else {
2422 Ident ident = CompletionEngine_this._createIdent(node);
2423 CompletionEngine_this._analyzeConstructorTypeName(ident);
2424 }
2425 return null;
2426 }
2427
2428 @override
2429 Object visitIsExpression(IsExpression node) {
2430 Ident ident;
2431 Token isToken = node.isOperator;
2432 int isTokenEnd = isToken.end;
2433 if (isTokenEnd == CompletionEngine_this._completionLocation()) {
2434 Expression expression = node.expression;
2435 int offset = isToken.offset;
2436 // { target.is! } possible name completion, parsed as "target.{synthetic} is!"
2437 if (expression is PrefixedIdentifier) {
2438 PrefixedIdentifier prefIdent = expression;
2439 if (prefIdent.identifier.isSynthetic) {
2440 CompletionEngine_this._analyzePrefixedAccess(prefIdent.prefix, new Ide nt.con2(node, "is", offset));
2441 } else {
2442 CompletionEngine_this._pKeyword(isToken);
2443 }
2444 return null;
2445 }
2446 // { expr is! }
2447 if (!CompletionEngine._isSyntheticIdentifier(expression)) {
2448 CompletionEngine_this._pKeyword(node.isOperator);
2449 return null;
2450 }
2451 // { is! } possible name completion
2452 ident = new Ident.con2(node, "is", offset);
2453 } else if (CompletionEngine_this._isCompletionAfter(isTokenEnd)) {
2454 CompletionEngine_this._state._isDynamicAllowed = false;
2455 CompletionEngine_this._state._isVoidAllowed = false;
2456 CompletionEngine_this._analyzeTypeName(CompletionEngine_this._createIdent( node), null);
2457 return null;
2458 } else {
2459 ident = CompletionEngine_this._createIdent(node);
2460 }
2461 CompletionEngine_this._analyzeLocalName(ident);
2462 return null;
2463 }
2464
2465 @override
2466 Object visitLibraryIdentifier(LibraryIdentifier node) => null;
2467
2468 @override
2469 Object visitMethodInvocation(MethodInvocation node) {
2470 Token period = node.period;
2471 if (period != null && CompletionEngine_this._isCompletionAfter(period.end)) {
2472 // { x.!y() }
2473 CompletionEngine_this._dispatchPrefixAnalysis2(node);
2474 }
2475 return null;
2476 }
2477
2478 @override
2479 Object visitNamespaceDirective(NamespaceDirective node) {
2480 StringLiteral uri = node.uri;
2481 if (uri != null && uri.isSynthetic && node.keyword.end <= CompletionEngine_t his._context.selectionOffset) {
2482 uri.accept(this);
2483 }
2484 return super.visitNamespaceDirective(node);
2485 }
2486
2487 @override
2488 Object visitPartOfDirective(PartOfDirective node) {
2489 if (CompletionEngine_this._isCompletingKeyword(node.ofToken)) {
2490 CompletionEngine_this._pKeyword(node.ofToken);
2491 } else {
2492 visitDirective(node);
2493 }
2494 return null;
2495 }
2496
2497 @override
2498 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
2499 if (CompletionEngine_this._isCompletionAfter(node.period.end)) {
2500 if (CompletionEngine_this._isCompletionBefore(node.identifier.offset)) {
2501 // { x.! } or { x.! y } Note missing/implied semicolon before y; this l ooks like an
2502 // obscure case but it occurs frequently when editing existing code.
2503 CompletionEngine_this._dispatchPrefixAnalysis3(node, node.identifier);
2504 }
2505 }
2506 return null;
2507 }
2508
2509 @override
2510 Object visitPropertyAccess(PropertyAccess node) {
2511 if (node.target != null && node.target.length == 0) {
2512 return null;
2513 }
2514 Expression target = node.realTarget;
2515 // The "1 + str.!.length" is parsed as "(1 + str).!.length",
2516 // but actually user wants "1 + (str.!).length".
2517 // So, if completion inside of period-period ".!." then it is not really a c ascade completion.
2518 Token operator = node.operator;
2519 if (operator.type == TokenType.PERIOD_PERIOD) {
2520 int completionLocation = CompletionEngine_this._completionLocation();
2521 if (completionLocation > operator.offset && completionLocation < operator. end) {
2522 while (target is BinaryExpression) {
2523 target = (target as BinaryExpression).rightOperand;
2524 }
2525 }
2526 }
2527 // do prefixed completion
2528 CompletionEngine_this._analyzePrefixedAccess(target, node.propertyName);
2529 return null;
2530 }
2531
2532 @override
2533 Object visitReturnStatement(ReturnStatement node) {
2534 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2535 CompletionEngine_this._pKeyword(node.keyword);
2536 return null;
2537 }
2538 Expression expression = node.expression;
2539 // return !
2540 if (expression is SimpleIdentifier) {
2541 SimpleIdentifier identifier = expression;
2542 CompletionEngine_this._analyzeLocalName(identifier);
2543 return null;
2544 }
2545 // return expression ! ;
2546 Token semicolon = node.semicolon;
2547 if (expression != null && semicolon != null && CompletionEngine_this._isComp letionBetween(expression.end, semicolon.offset)) {
2548 CompletionEngine_this._operatorAccess(expression, CompletionEngine_this._c reateIdent(node));
2549 return null;
2550 }
2551 return null;
2552 }
2553
2554 @override
2555 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
2556 if (node.keyword != null && CompletionEngine_this._isCompletionBefore(node.k eyword.end)) {
2557 // f() { g(var! z) }
2558 Token token = node.keyword;
2559 Ident ident = new Ident.con3(node, token);
2560 CompletionEngine_this._analyzeTypeName(ident, ident);
2561 }
2562 return null;
2563 }
2564
2565 @override
2566 Object visitSimpleIdentifier(SimpleIdentifier node) {
2567 AstNode parent = node.parent;
2568 if (parent != null) {
2569 CompletionEngine_IdentifierCompleter visitor = new CompletionEngine_Identi fierCompleter(CompletionEngine_this, node);
2570 return parent.accept(visitor);
2571 }
2572 return null;
2573 }
2574
2575 @override
2576 Object visitSimpleStringLiteral(SimpleStringLiteral node) {
2577 AstNode parent = node.parent;
2578 if (parent is Directive) {
2579 CompletionEngine_StringCompleter visitor = new CompletionEngine_StringComp leter(CompletionEngine_this, node);
2580 return parent.accept(visitor);
2581 }
2582 return null;
2583 }
2584
2585 @override
2586 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
2587 CompletionEngine_this._analyzeSuperConstructorInvocation(node);
2588 return null;
2589 }
2590
2591 @override
2592 Object visitSwitchMember(SwitchMember node) {
2593 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2594 CompletionEngine_this._pKeyword(node.keyword);
2595 }
2596 return null;
2597 }
2598
2599 @override
2600 Object visitSwitchStatement(SwitchStatement node) {
2601 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2602 CompletionEngine_this._pKeyword(node.keyword);
2603 }
2604 return null;
2605 }
2606
2607 @override
2608 Object visitTryStatement(TryStatement node) {
2609 if (CompletionEngine_this._isCompletingKeyword(node.tryKeyword)) {
2610 CompletionEngine_this._pKeyword(node.tryKeyword);
2611 }
2612 return null;
2613 }
2614
2615 @override
2616 Object visitTypeArgumentList(TypeArgumentList node) {
2617 if (CompletionEngine_this._isCompletionBetween(node.leftBracket.end, node.ri ghtBracket.offset)) {
2618 CompletionEngine_this._analyzeTypeName(CompletionEngine_this._createIdent( node), null);
2619 }
2620 return null;
2621 }
2622
2623 @override
2624 Object visitTypeParameter(TypeParameter node) {
2625 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2626 CompletionEngine_this._pKeyword(node.keyword);
2627 } else if (node.name.name.isEmpty && CompletionEngine_this._isCompletionBefo re(node.keyword.offset)) {
2628 // { < ! extends X> }
2629 CompletionEngine_this._analyzeTypeName(node.name, CompletionEngine_this._t ypeDeclarationName(node));
2630 }
2631 // { <! X ! extends ! Y !> }
2632 return null;
2633 }
2634
2635 @override
2636 Object visitTypeParameterList(TypeParameterList node) {
2637 // { <X extends A,! B,! > }
2638 if (CompletionEngine_this._isCompletionBetween(node.leftBracket.end, node.ri ghtBracket.offset)) {
2639 CompletionEngine_this._analyzeTypeName(CompletionEngine_this._createIdent( node), CompletionEngine_this._typeDeclarationName(node));
2640 }
2641 return null;
2642 }
2643
2644 @override
2645 Object visitVariableDeclaration(VariableDeclaration node) {
2646 if (CompletionEngine_this._isCompletionAfter(node.equals.end)) {
2647 // { var x =! ...}
2648 CompletionEngine_this._analyzeLocalName(CompletionEngine_this._createIdent (node));
2649 }
2650 return null;
2651 }
2652
2653 @override
2654 Object visitVariableDeclarationList(VariableDeclarationList node) {
2655 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2656 CompletionEngine_this._pKeyword(node.keyword);
2657 CompletionEngine_this._analyzeTypeName(new Ident.con3(node, node.keyword), null);
2658 }
2659 return null;
2660 }
2661
2662 @override
2663 Object visitWhileStatement(WhileStatement node) {
2664 if (CompletionEngine_this._isCompletingKeyword(node.keyword)) {
2665 CompletionEngine_this._pKeyword(node.keyword);
2666 } else if (CompletionEngine_this._isCompletionBetween(node.condition.end, no de.rightParenthesis.offset)) {
2667 CompletionEngine_this._operatorAccess(node.condition, CompletionEngine_thi s._createIdent(node));
2668 }
2669 return null;
2670 }
2671
2672 @override
2673 Object visitWithClause(WithClause node) {
2674 if (CompletionEngine_this._isCompletingKeyword(node.withKeyword)) {
2675 CompletionEngine_this._pKeyword(node.withKeyword);
2676 } else if (node.mixinTypes.isEmpty) {
2677 // { X with ! }
2678 CompletionEngine_this._analyzeTypeName(CompletionEngine_this._createIdent( node), CompletionEngine_this._typeDeclarationName(node));
2679 } else {
2680 // { X with ! Y }
2681 CompletionEngine_this._analyzeTypeName(CompletionEngine_this._createIdent( node), CompletionEngine_this._typeDeclarationName(node));
2682 }
2683 return null;
2684 }
2685 }
2686
2687 /**
2688 * A TypeNameCompleter is used to classify the parent of a SimpleIdentifier afte r it has been
2689 * identified as a TypeName by the IdentifierCompleter.
2690 */
2691 class CompletionEngine_TypeNameCompleter extends CompletionEngine_AstNodeClassif ier {
2692 final CompletionEngine CompletionEngine_this;
2693
2694 final SimpleIdentifier _identifier;
2695
2696 final TypeName _typeName;
2697
2698 CompletionEngine_TypeNameCompleter(this.CompletionEngine_this, this._identifie r, this._typeName);
2699
2700 @override
2701 Object visitAsExpression(AsExpression node) {
2702 if (identical(node.type, _typeName)) {
2703 CompletionEngine_this._state._isDynamicAllowed = false;
2704 CompletionEngine_this._state._isVoidAllowed = false;
2705 CompletionEngine_this._analyzeTypeName(_identifier, null);
2706 }
2707 return null;
2708 }
2709
2710 @override
2711 Object visitCatchClause(CatchClause node) {
2712 if (identical(node.exceptionType, _typeName)) {
2713 CompletionEngine_this._analyzeTypeName(_identifier, null);
2714 }
2715 return null;
2716 }
2717
2718 @override
2719 Object visitClassTypeAlias(ClassTypeAlias node) {
2720 CompletionEngine_this._analyzeTypeName(_identifier, CompletionEngine_this._t ypeDeclarationName(node));
2721 return null;
2722 }
2723
2724 @override
2725 Object visitConstructorName(ConstructorName node) {
2726 if (identical(_typeName, node.type)) {
2727 if (node.period != null) {
2728 if (CompletionEngine_this._isCompletionAfter(node.period.end)) {
2729 // Is this branch reachable? Probably only in IdentifierCompleter.
2730 "".toString();
2731 } else {
2732 // { new Cla!ss.cons() }
2733 Element element = _identifier.bestElement;
2734 if (element is ClassElement) {
2735 CompletionEngine_this._namedConstructorReference(element, _identifie r);
2736 }
2737 }
2738 } else {
2739 // { new ! } { new Na!me(); } { new js!on. }
2740 CompletionEngine_this._analyzeConstructorTypeName(_identifier);
2741 }
2742 }
2743 return null;
2744 }
2745
2746 @override
2747 Object visitExtendsClause(ExtendsClause node) {
2748 CompletionEngine_this._analyzeTypeName(_identifier, CompletionEngine_this._t ypeDeclarationName(node));
2749 return null;
2750 }
2751
2752 @override
2753 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
2754 CompletionEngine_this._analyzeTypeName(_identifier, CompletionEngine_this._t ypeDeclarationName(node));
2755 return null;
2756 }
2757
2758 @override
2759 Object visitImplementsClause(ImplementsClause node) {
2760 CompletionEngine_this._analyzeTypeName(_identifier, CompletionEngine_this._t ypeDeclarationName(node));
2761 return null;
2762 }
2763
2764 @override
2765 Object visitIsExpression(IsExpression node) {
2766 if (identical(_typeName, node.type)) {
2767 Token isToken = node.isOperator;
2768 if (CompletionEngine_this._completionLocation() == isToken.end) {
2769 Expression expression = node.expression;
2770 int offset = isToken.offset;
2771 // { target.is! } possible name completion, parsed as "target.{synthetic } is!"
2772 if (expression is PrefixedIdentifier) {
2773 PrefixedIdentifier prefIdent = expression;
2774 if (prefIdent.identifier.isSynthetic) {
2775 CompletionEngine_this._analyzePrefixedAccess(prefIdent.prefix, new I dent.con2(node, "is", offset));
2776 } else {
2777 CompletionEngine_this._pKeyword(node.isOperator);
2778 }
2779 return null;
2780 }
2781 // { expr is! }
2782 if (!CompletionEngine._isSyntheticIdentifier(expression)) {
2783 CompletionEngine_this._pKeyword(node.isOperator);
2784 return null;
2785 }
2786 // { is! } possible name completion
2787 CompletionEngine_this._analyzeLocalName(new Ident.con2(node, "is", offse t));
2788 } else {
2789 CompletionEngine_this._analyzeTypeName(node.type.name as SimpleIdentifie r, null);
2790 }
2791 }
2792 return null;
2793 }
2794
2795 @override
2796 Object visitMethodDeclaration(MethodDeclaration node) {
2797 if (identical(node.returnType, _typeName)) {
2798 CompletionEngine_this._analyzeTypeName(_identifier, null);
2799 }
2800 return null;
2801 }
2802
2803 @override
2804 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
2805 CompletionEngine_this._analyzeTypeName(_identifier, null);
2806 return null;
2807 }
2808
2809 @override
2810 Object visitTypeArgumentList(TypeArgumentList node) {
2811 if (CompletionEngine_this._isCompletionBetween(node.leftBracket.end, node.ri ghtBracket.offset)) {
2812 CompletionEngine_this._analyzeTypeName(_identifier, null);
2813 }
2814 return null;
2815 }
2816
2817 @override
2818 Object visitTypeParameter(TypeParameter node) {
2819 if (identical(node.bound, _typeName)) {
2820 // { X<A extends !Y> }
2821 CompletionEngine_this._analyzeTypeName(_identifier, CompletionEngine_this. _typeDeclarationName(node));
2822 }
2823 return null;
2824 }
2825
2826 @override
2827 Object visitVariableDeclarationList(VariableDeclarationList node) {
2828 if (node.parent is Statement) {
2829 CompletionEngine_this._analyzeLocalName(_identifier);
2830 } else {
2831 CompletionEngine_this._analyzeTypeName(_identifier, null);
2832 }
2833 return null;
2834 }
2835
2836 @override
2837 Object visitWithClause(WithClause node) {
2838 CompletionEngine_this._analyzeTypeName(_identifier, CompletionEngine_this._t ypeDeclarationName(node));
2839 return null;
2840 }
2841 }
2842
2843 /**
2844 * The factory class used to create completion proposals.
2845 */
2846 class CompletionFactory {
2847 /**
2848 * Create a completion proposal of the given kind.
2849 */
2850 CompletionProposal createCompletionProposal(CompletionSuggestionKind kind, int insertionPoint) {
2851 CompletionProposalImpl prop = new CompletionProposalImpl();
2852 prop.setKind(kind);
2853 prop.setLocation(insertionPoint);
2854 return prop;
2855 }
2856 }
2857
2858 abstract class CompletionProposal {
2859 static final int RELEVANCE_LOW = 0;
2860
2861 static final int RELEVANCE_DEFAULT = 10;
2862
2863 static final int RELEVANCE_HIGH = 20;
2864
2865 /**
2866 * This character is used to specify location of the cursor after completion.
2867 */
2868 static final int CURSOR_MARKER = 0x2758;
2869
2870 void applyPartitionOffset(int partitionOffset);
2871
2872 String get completion;
2873
2874 String get declaringType;
2875
2876 Element get element;
2877
2878 CompletionSuggestionKind get kind;
2879
2880 int get location;
2881
2882 String get parameterName;
2883
2884 List<String> get parameterNames;
2885
2886 String get parameterType;
2887
2888 List<String> get parameterTypes;
2889
2890 int get positionalParameterCount;
2891
2892 int get relevance;
2893
2894 int get replacementLength;
2895
2896 int get replacementLengthIdentifier;
2897
2898 String get returnType;
2899
2900 bool get hasNamed;
2901
2902 bool get hasPositional;
2903
2904 CompletionProposal incRelevance();
2905
2906 bool get isDeprecated;
2907
2908 bool get isPotentialMatch;
2909
2910 CompletionProposal setCompletion(String x);
2911
2912 CompletionProposal setDeclaringType(String name);
2913
2914 CompletionProposal setDeprecated(bool deprecated);
2915
2916 CompletionProposal setElement(Element element);
2917
2918 CompletionProposal setKind(CompletionSuggestionKind x);
2919
2920 CompletionProposal setLocation(int x);
2921
2922 CompletionProposal setParameterName(String paramName);
2923
2924 CompletionProposal setParameterNames(List<String> paramNames);
2925
2926 CompletionProposal setParameterStyle(int count, bool named, bool positional);
2927
2928 CompletionProposal setParameterType(String paramType);
2929
2930 CompletionProposal setParameterTypes(List<String> paramTypes);
2931
2932 CompletionProposal setPotentialMatch(bool isPotentialMatch);
2933
2934 CompletionProposal setRelevance(int n);
2935
2936 CompletionProposal setReplacementLength(int x);
2937
2938 CompletionProposal setReplacementLengthIdentifier(int x);
2939
2940 CompletionProposal setReturnType(String name);
2941 }
2942
2943 class CompletionProposalImpl implements CompletionProposal {
2944 Element _element;
2945
2946 String _completion = "";
2947
2948 String _returnType = "";
2949
2950 String _declaringType = "";
2951
2952 List<String> _parameterNames = StringUtilities.EMPTY_ARRAY;
2953
2954 List<String> _parameterTypes = StringUtilities.EMPTY_ARRAY;
2955
2956 String _parameterName;
2957
2958 String _parameterType;
2959
2960 CompletionSuggestionKind _kind = null;
2961
2962 int _location = 0;
2963
2964 int _replacementLength = 0;
2965
2966 int _replacementLength2 = 0;
2967
2968 int _positionalParameterCount = 0;
2969
2970 bool _named = false;
2971
2972 bool _positional = false;
2973
2974 bool _deprecated = false;
2975
2976 bool _potential = false;
2977
2978 int _relevance = CompletionProposal.RELEVANCE_DEFAULT;
2979
2980 @override
2981 void applyPartitionOffset(int partitionOffset) {
2982 _location += partitionOffset;
2983 }
2984
2985 @override
2986 String get completion => _completion;
2987
2988 @override
2989 String get declaringType => _declaringType;
2990
2991 @override
2992 Element get element => _element;
2993
2994 @override
2995 CompletionSuggestionKind get kind => _kind;
2996
2997 @override
2998 int get location => _location;
2999
3000 @override
3001 String get parameterName => _parameterName;
3002
3003 @override
3004 List<String> get parameterNames => _parameterNames;
3005
3006 @override
3007 String get parameterType => _parameterType;
3008
3009 @override
3010 List<String> get parameterTypes => _parameterTypes;
3011
3012 @override
3013 int get positionalParameterCount => _positionalParameterCount;
3014
3015 @override
3016 int get relevance => _relevance;
3017
3018 @override
3019 int get replacementLength => _replacementLength;
3020
3021 @override
3022 int get replacementLengthIdentifier => _replacementLength2;
3023
3024 @override
3025 String get returnType => _returnType;
3026
3027 @override
3028 bool get hasNamed => _named;
3029
3030 @override
3031 bool get hasPositional => _positional;
3032
3033 @override
3034 CompletionProposal incRelevance() {
3035 _relevance++;
3036 return this;
3037 }
3038
3039 @override
3040 bool get isDeprecated => _deprecated;
3041
3042 @override
3043 bool get isPotentialMatch => _potential;
3044
3045 @override
3046 CompletionProposal setCompletion(String x) {
3047 _completion = x;
3048 if (_replacementLength == 0) {
3049 setReplacementLength(x.length);
3050 }
3051 return this;
3052 }
3053
3054 @override
3055 CompletionProposal setDeclaringType(String name) {
3056 _declaringType = name;
3057 return this;
3058 }
3059
3060 @override
3061 CompletionProposal setDeprecated(bool deprecated) {
3062 this._deprecated = deprecated;
3063 return this;
3064 }
3065
3066 @override
3067 CompletionProposal setElement(Element element) {
3068 this._element = element;
3069 return this;
3070 }
3071
3072 @override
3073 CompletionProposal setKind(CompletionSuggestionKind x) {
3074 _kind = x;
3075 return this;
3076 }
3077
3078 @override
3079 CompletionProposal setLocation(int x) {
3080 _location = x;
3081 return this;
3082 }
3083
3084 @override
3085 CompletionProposal setParameterName(String parameterName) {
3086 this._parameterName = parameterName;
3087 return this;
3088 }
3089
3090 @override
3091 CompletionProposal setParameterNames(List<String> paramNames) {
3092 _parameterNames = paramNames;
3093 return this;
3094 }
3095
3096 @override
3097 CompletionProposal setParameterStyle(int count, bool named, bool positional) {
3098 this._named = named;
3099 this._positional = positional;
3100 this._positionalParameterCount = count;
3101 return this;
3102 }
3103
3104 @override
3105 CompletionProposal setParameterType(String parameterType) {
3106 this._parameterType = parameterType;
3107 return this;
3108 }
3109
3110 @override
3111 CompletionProposal setParameterTypes(List<String> paramTypes) {
3112 _parameterTypes = paramTypes;
3113 return this;
3114 }
3115
3116 @override
3117 CompletionProposal setPotentialMatch(bool isPotentialMatch) {
3118 _potential = isPotentialMatch;
3119 return this;
3120 }
3121
3122 @override
3123 CompletionProposal setRelevance(int n) {
3124 _relevance = n;
3125 return this;
3126 }
3127
3128 @override
3129 CompletionProposal setReplacementLength(int x) {
3130 _replacementLength = x;
3131 return this;
3132 }
3133
3134 @override
3135 CompletionProposal setReplacementLengthIdentifier(int x) {
3136 _replacementLength2 = x;
3137 return this;
3138 }
3139
3140 @override
3141 CompletionProposal setReturnType(String name) {
3142 _returnType = name;
3143 return this;
3144 }
3145 }
3146
3147 /**
3148 * A pathway for reporting completion proposals back to the client.
3149 */
3150 abstract class CompletionRequestor {
3151 /**
3152 * Record the given completion proposal for eventual presentation to the user.
3153 */
3154 accept(CompletionProposal proposal);
3155
3156 void beginReporting();
3157
3158 void endReporting();
3159 }
3160
3161 /**
3162 */
3163 class CompletionState {
3164 bool _isForMixin = false;
3165
3166 bool _isVoidAllowed = false;
3167
3168 bool _isDynamicAllowed = false;
3169
3170 bool _isSourceDeclarationStatic = false;
3171
3172 bool _isThisAllowed = true;
3173
3174 bool _isVarAllowed = false;
3175
3176 bool _areLiteralsAllowed = false;
3177
3178 bool _areLiteralsProhibited = false;
3179
3180 bool _areOperatorsAllowed = false;
3181
3182 bool _areStaticReferencesProhibited = false;
3183
3184 bool _areInstanceReferencesProhibited = false;
3185
3186 bool _areUndefinedTypesProhibited = false;
3187
3188 bool _isCompileTimeConstantRequired = false;
3189
3190 bool _isOptionalArgumentRequired = false;
3191
3192 bool _areMethodsProhibited = false;
3193
3194 bool _areClassesRequired = false;
3195
3196 ParameterElement _targetParameter;
3197
3198 void mustBeInstantiableType() {
3199 _areClassesRequired = true;
3200 _prohibitsLiterals();
3201 }
3202
3203 void _includesLiterals() {
3204 if (!_areLiteralsProhibited) {
3205 _areLiteralsAllowed = true;
3206 }
3207 }
3208
3209 void _includesOperators() {
3210 _areOperatorsAllowed = true;
3211 }
3212
3213 void _includesUndefinedDeclarationTypes() {
3214 if (!_areUndefinedTypesProhibited) {
3215 _isVoidAllowed = true;
3216 _isDynamicAllowed = true;
3217 }
3218 }
3219
3220 void _includesUndefinedTypes() {
3221 _isVarAllowed = true;
3222 _isDynamicAllowed = true;
3223 }
3224
3225 void _mustBeMixin() {
3226 _isForMixin = true;
3227 }
3228
3229 void _prohibitsInstanceReferences() {
3230 _areInstanceReferencesProhibited = true;
3231 }
3232
3233 void _prohibitsLiterals() {
3234 _areLiteralsAllowed = false;
3235 _areLiteralsProhibited = true;
3236 }
3237
3238 void _prohibitsStaticReferences() {
3239 _areStaticReferencesProhibited = true;
3240 }
3241
3242 void _prohibitThis() {
3243 _isThisAllowed = false;
3244 }
3245
3246 void _prohibitsUndefinedTypes() {
3247 _areUndefinedTypesProhibited = true;
3248 }
3249
3250 void _requiresConst(bool isConst) {
3251 _isCompileTimeConstantRequired = isConst;
3252 }
3253
3254 void _requiresOperators() {
3255 _includesOperators();
3256 _areMethodsProhibited = true;
3257 }
3258
3259 void _requiresOptionalArgument() {
3260 _isOptionalArgumentRequired = true;
3261 _prohibitsLiterals();
3262 }
3263
3264 void set context(AstNode base) {
3265 base.accept(new ContextAnalyzer(this, base));
3266 }
3267
3268 void _sourceDeclarationIsStatic(bool state) {
3269 _isSourceDeclarationStatic = state;
3270 if (state) {
3271 if (!_areStaticReferencesProhibited) {
3272 _prohibitsInstanceReferences();
3273 }
3274 }
3275 }
3276 }
3277
3278 /**
3279 */
3280 class ContextAnalyzer extends GeneralizingAstVisitor<Object> {
3281 final CompletionState _state;
3282
3283 final AstNode _completionNode;
3284
3285 AstNode _child;
3286
3287 bool _inExpression = false;
3288
3289 bool _inIdentifier = false;
3290
3291 bool _inTypeName = false;
3292
3293 bool _maybeInvocationArgument = true;
3294
3295 ContextAnalyzer(this._state, this._completionNode);
3296
3297 @override
3298 Object visitAnnotation(Annotation node) {
3299 _state._requiresConst(true);
3300 return super.visitAnnotation(node);
3301 }
3302
3303 @override
3304 Object visitCatchClause(CatchClause node) {
3305 if (identical(node.exceptionType, _child)) {
3306 _state._prohibitsLiterals();
3307 }
3308 return null;
3309 }
3310
3311 @override
3312 Object visitCompilationUnitMember(CompilationUnitMember node) {
3313 if (node is! ClassDeclaration) {
3314 _state._prohibitThis();
3315 }
3316 return super.visitCompilationUnitMember(node);
3317 }
3318
3319 @override
3320 Object visitConstructorInitializer(ConstructorInitializer node) {
3321 _state._prohibitThis();
3322 return super.visitConstructorInitializer(node);
3323 }
3324
3325 @override
3326 Object visitDirective(Directive node) {
3327 _state._prohibitsLiterals();
3328 return super.visitDirective(node);
3329 }
3330
3331 @override
3332 Object visitDoStatement(DoStatement node) {
3333 if (identical(_child, node.condition)) {
3334 _state._includesLiterals();
3335 }
3336 return super.visitDoStatement(node);
3337 }
3338
3339 @override
3340 Object visitExpression(Expression node) {
3341 _inExpression = true;
3342 _state._includesLiterals();
3343 _mayBeSetParameterElement(node);
3344 return super.visitExpression(node);
3345 }
3346
3347 @override
3348 Object visitFieldDeclaration(FieldDeclaration node) {
3349 _state._prohibitThis();
3350 return super.visitFieldDeclaration(node);
3351 }
3352
3353 @override
3354 Object visitForEachStatement(ForEachStatement node) {
3355 if (identical(_child, node.iterator)) {
3356 _state._includesLiterals();
3357 }
3358 return super.visitForEachStatement(node);
3359 }
3360
3361 @override
3362 Object visitFunctionExpression(FunctionExpression node) {
3363 if (node.parent is Declaration) {
3364 // Function expressions that are part of a declaration are not to be treat ed as expressions.
3365 return visitNode(node);
3366 } else {
3367 return visitExpression(node);
3368 }
3369 }
3370
3371 @override
3372 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
3373 if (_inTypeName || node.returnType == null) {
3374 // This may be an incomplete class type alias
3375 _state._includesUndefinedDeclarationTypes();
3376 }
3377 return super.visitFunctionTypeAlias(node);
3378 }
3379
3380 @override
3381 Object visitIdentifier(Identifier node) {
3382 _mayBeSetParameterElement(node);
3383 // Identifiers cannot safely be generalized to expressions, so just walk up one level.
3384 // LibraryIdentifier is never an expression. PrefixedIdentifier may be an ex pression, but
3385 // not in a catch-clause or a declaration. SimpleIdentifier may be an expres sion, but not
3386 // in a constructor name, label, or where PrefixedIdentifier is not.
3387 return visitNode(node);
3388 }
3389
3390 @override
3391 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
3392 _state._requiresConst(node.isConst);
3393 if (identical(_completionNode.parent.parent, _child)) {
3394 _state.mustBeInstantiableType();
3395 }
3396 return super.visitInstanceCreationExpression(node);
3397 }
3398
3399 @override
3400 Object visitMethodDeclaration(MethodDeclaration node) {
3401 _state._sourceDeclarationIsStatic(node.isStatic);
3402 if (identical(_child, node.returnType)) {
3403 _state._includesUndefinedDeclarationTypes();
3404 }
3405 if (node.isStatic) {
3406 _state._prohibitThis();
3407 }
3408 return super.visitMethodDeclaration(node);
3409 }
3410
3411 @override
3412 Object visitNode(AstNode node) {
3413 // Walk UP the tree, not down.
3414 AstNode parent = node.parent;
3415 _updateIfShouldGetTargetParameter(node, parent);
3416 if (parent != null) {
3417 _child = node;
3418 parent.accept(this);
3419 }
3420 return null;
3421 }
3422
3423 @override
3424 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
3425 if (identical(node, _completionNode) || identical(node.identifier, _completi onNode)) {
3426 SimpleIdentifier prefix = node.prefix;
3427 if (_isClassLiteral(prefix)) {
3428 _state._prohibitsInstanceReferences();
3429 } else {
3430 _state._prohibitsStaticReferences();
3431 }
3432 }
3433 return super.visitPrefixedIdentifier(node);
3434 }
3435
3436 @override
3437 Object visitPropertyAccess(PropertyAccess node) {
3438 if (identical(node, _completionNode) || identical(node.propertyName, _comple tionNode)) {
3439 Expression target = node.realTarget;
3440 if (_isClassLiteral(target)) {
3441 _state._prohibitsInstanceReferences();
3442 } else {
3443 _state._prohibitsStaticReferences();
3444 }
3445 }
3446 return super.visitPropertyAccess(node);
3447 }
3448
3449 @override
3450 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
3451 _state._includesUndefinedTypes();
3452 return super.visitSimpleFormalParameter(node);
3453 }
3454
3455 @override
3456 Object visitSimpleIdentifier(SimpleIdentifier node) {
3457 _inIdentifier = true;
3458 return super.visitSimpleIdentifier(node);
3459 }
3460
3461 @override
3462 Object visitSwitchStatement(SwitchStatement node) {
3463 if (identical(_child, node.expression)) {
3464 _state._includesLiterals();
3465 }
3466 return super.visitSwitchStatement(node);
3467 }
3468
3469 @override
3470 Object visitTypeArgumentList(TypeArgumentList node) {
3471 _state._prohibitsUndefinedTypes();
3472 return super.visitTypeArgumentList(node);
3473 }
3474
3475 @override
3476 Object visitTypeName(TypeName node) {
3477 _inTypeName = true;
3478 return super.visitTypeName(node);
3479 }
3480
3481 @override
3482 Object visitVariableDeclaration(VariableDeclaration node) {
3483 if (identical(node.name, _completionNode)) {
3484 _state._prohibitsLiterals();
3485 }
3486 return super.visitVariableDeclaration(node);
3487 }
3488
3489 @override
3490 Object visitVariableDeclarationList(VariableDeclarationList node) {
3491 _state._includesUndefinedDeclarationTypes();
3492 return super.visitVariableDeclarationList(node);
3493 }
3494
3495 @override
3496 Object visitWhileStatement(WhileStatement node) {
3497 if (identical(_child, node.condition)) {
3498 _state._includesLiterals();
3499 }
3500 return super.visitWhileStatement(node);
3501 }
3502
3503 @override
3504 Object visitWithClause(WithClause node) {
3505 _state._mustBeMixin();
3506 return super.visitWithClause(node);
3507 }
3508
3509 bool _isClassLiteral(Expression expression) => expression is Identifier && exp ression.staticElement is ClassElement;
3510
3511 void _mayBeSetParameterElement(Expression node) {
3512 if (!_maybeInvocationArgument) {
3513 return;
3514 }
3515 if (node.parent is ArgumentList) {
3516 if (_state._targetParameter == null) {
3517 _state._targetParameter = node.bestParameterElement;
3518 }
3519 }
3520 }
3521
3522 void _updateIfShouldGetTargetParameter(AstNode node, AstNode parent) {
3523 if (!_maybeInvocationArgument) {
3524 return;
3525 }
3526 // prefix.node
3527 if (parent is PrefixedIdentifier) {
3528 if (identical(parent.identifier, node)) {
3529 return;
3530 }
3531 }
3532 // something unknown
3533 _maybeInvocationArgument = false;
3534 }
3535 }
3536
3537 class Filter {
3538 String _prefix;
3539
3540 String _originalPrefix;
3541
3542 RegExp _pattern;
3543
3544 Filter.con1(SimpleIdentifier ident, int loc) : this.con2(ident.name, ident.off set, loc);
3545
3546 Filter.con2(String name, int pos, int loc) {
3547 int len = loc - pos;
3548 if (len > 0) {
3549 if (len <= name.length) {
3550 _prefix = name.substring(0, len);
3551 } else {
3552 _prefix = name;
3553 }
3554 } else {
3555 _prefix = "";
3556 }
3557 _originalPrefix = _prefix;
3558 _prefix = _prefix.toLowerCase();
3559 }
3560
3561 /**
3562 * @return `true` if the given name starts with the same prefix as used for fi lter.
3563 */
3564 bool _isSameCasePrefix(String name) => name.startsWith(_originalPrefix);
3565
3566 String _makePattern() {
3567 // TODO(scheglov) translate it
3568 return null;
3569 }
3570
3571 bool _match(Element elem) => _match2(elem.displayName);
3572
3573 bool _match2(String name) {
3574 // Return true if the filter passes.
3575 if (name.toLowerCase().startsWith(_prefix)) {
3576 return true;
3577 }
3578 return _matchPattern(name);
3579 }
3580
3581 void _removeNotMatching(List<Element> elements) {
3582 for (int i = elements.length - 1; i >= 0; i--) {
3583 if (!_match(elements[i])) {
3584 elements.removeAt(i);
3585 }
3586 }
3587 }
3588
3589 bool _matchPattern(String name) {
3590 // TODO(scheglov) translate it
3591 return false;
3592 }
3593 }
3594
3595 class GeneralizingAstVisitor_CompletionEngine_copyWithout extends GeneralizingAs tVisitor<Object> {
3596 AstNode deletion;
3597
3598 List<FormalParameter> newList;
3599
3600 GeneralizingAstVisitor_CompletionEngine_copyWithout(this.deletion, this.newLis t) : super();
3601
3602 @override
3603 Object visitNode(AstNode node) {
3604 if (!identical(node, deletion)) {
3605 newList.add(node as FormalParameter);
3606 }
3607 return null;
3608 }
3609 }
3610
3611 /**
3612 * An [Ident] is a wrapper for a String that provides type equivalence with Simp leIdentifier.
3613 */
3614 class Ident extends EphemeralIdentifier {
3615 String _name;
3616
3617 Ident.con1(AstNode parent, int offset) : super(parent, offset);
3618
3619 Ident.con2(AstNode parent, String name, int offset) : super(parent, offset) {
3620 this._name = name;
3621 }
3622
3623 Ident.con3(AstNode parent, Token name) : super(parent, name.offset) {
3624 this._name = name.lexeme;
3625 }
3626
3627 @override
3628 String get name {
3629 if (_name != null) {
3630 return _name;
3631 }
3632 String n = super.name;
3633 if (n != null) {
3634 return n;
3635 }
3636 return "";
3637 }
3638 }
3639
3640 class ProposalCollector implements CompletionRequestor {
3641 final CompletionRequestor requestor;
3642
3643 List<CompletionProposal> _proposals;
3644
3645 ProposalCollector(this.requestor) {
3646 this._proposals = new List<CompletionProposal>();
3647 }
3648
3649 @override
3650 accept(CompletionProposal proposal) {
3651 _proposals.add(proposal);
3652 }
3653
3654 @override
3655 void beginReporting() {
3656 requestor.beginReporting();
3657 }
3658
3659 @override
3660 void endReporting() {
3661 requestor.endReporting();
3662 }
3663
3664 List<CompletionProposal> get proposals => _proposals;
3665 }
3666
3667 class SearchFilter_CompletionEngine_allSubtypes implements SearchFilter {
3668 ClassElement classElement;
3669
3670 SearchFilter_CompletionEngine_allSubtypes(this.classElement);
3671
3672 @override
3673 bool passes(SearchMatch match) {
3674 Element element = match.element;
3675 if (element is ClassElement) {
3676 ClassElement clElem = element;
3677 while (clElem != null) {
3678 InterfaceType ifType = clElem.supertype;
3679 if (ifType == null) {
3680 return false;
3681 }
3682 clElem = ifType.element;
3683 if (identical(clElem, classElement)) {
3684 return true;
3685 }
3686 }
3687 }
3688 return false;
3689 }
3690 }
3691
3692 class TopLevelNamesKind extends Enum<TopLevelNamesKind> {
3693 static const TopLevelNamesKind DECLARED_AND_IMPORTS = const TopLevelNamesKind( 'DECLARED_AND_IMPORTS', 0);
3694
3695 static const TopLevelNamesKind DECLARED_AND_EXPORTS = const TopLevelNamesKind( 'DECLARED_AND_EXPORTS', 1);
3696
3697 static const List<TopLevelNamesKind> values = const [DECLARED_AND_IMPORTS, DEC LARED_AND_EXPORTS];
3698
3699 const TopLevelNamesKind(String name, int ordinal) : super(name, ordinal);
3700 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/generated/stubs.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698