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

Side by Side Diff: pkg/analysis_services/lib/src/generated/completion.dart

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

Powered by Google App Engine
This is Rietveld 408576698