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

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

Issue 1068483002: rename completion source files to match content (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 8 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 library services.completion.contributor.dart.local;
6
7 import 'dart:async';
8
9 import 'package:analysis_server/src/protocol.dart' as protocol
10 show Element, ElementKind;
11 import 'package:analysis_server/src/protocol.dart' hide Element, ElementKind;
12 import 'package:analysis_server/src/services/completion/dart_completion_manager. dart';
13 import 'package:analysis_server/src/services/completion/local_declaration_visito r.dart';
14 import 'package:analysis_server/src/services/completion/optype.dart';
15 import 'package:analyzer/src/generated/ast.dart';
16 import 'package:analyzer/src/generated/scanner.dart';
17 import 'package:analyzer/src/generated/utilities_dart.dart';
18
19 const _DYNAMIC = 'dynamic';
20
21 final TypeName _NO_RETURN_TYPE = new TypeName(
22 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), null);
23
24 /**
25 * Create a new protocol Element for inclusion in a completion suggestion.
26 */
27 protocol.Element _createElement(protocol.ElementKind kind, SimpleIdentifier id,
28 {String parameters, TypeName returnType, bool isAbstract: false,
29 bool isDeprecated: false}) {
30 String name = id != null ? id.name : '';
31 int flags = protocol.Element.makeFlags(
32 isAbstract: isAbstract,
33 isDeprecated: isDeprecated,
34 isPrivate: Identifier.isPrivateName(name));
35 return new protocol.Element(kind, name, flags,
36 parameters: parameters, returnType: _nameForType(returnType));
37 }
38
39 /**
40 * Return `true` if the @deprecated annotation is present
41 */
42 bool _isDeprecated(AnnotatedNode node) {
43 if (node != null) {
44 NodeList<Annotation> metadata = node.metadata;
45 if (metadata != null) {
46 return metadata.any((Annotation a) {
47 return a.name is SimpleIdentifier && a.name.name == 'deprecated';
48 });
49 }
50 }
51 return false;
52 }
53
54 /**
55 * Return the name for the given type.
56 */
57 String _nameForType(TypeName type) {
58 if (type == _NO_RETURN_TYPE) {
59 return null;
60 }
61 if (type == null) {
62 return _DYNAMIC;
63 }
64 Identifier id = type.name;
65 if (id == null) {
66 return _DYNAMIC;
67 }
68 String name = id.name;
69 if (name == null || name.length <= 0) {
70 return _DYNAMIC;
71 }
72 TypeArgumentList typeArgs = type.typeArguments;
73 if (typeArgs != null) {
74 //TODO (danrubel) include type arguments
75 }
76 return name;
77 }
78
79 /**
80 * A contributor for calculating `completion.getSuggestions` request results
81 * for the local library in which the completion is requested.
82 */
83 class LocalReferenceContributor extends DartCompletionContributor {
84 @override
85 bool computeFast(DartCompletionRequest request) {
86 OpType optype = request.optype;
87
88 // Collect suggestions from the specific child [AstNode] that contains
89 // the completion offset and all of its parents recursively.
90 if (optype.includeReturnValueSuggestions ||
91 optype.includeTypeNameSuggestions ||
92 optype.includeVoidReturnSuggestions) {
93 _LocalVisitor localVisitor =
94 new _LocalVisitor(request, request.offset, optype);
95 localVisitor.visit(request.target.containingNode);
96 }
97 if (optype.includeStatementLabelSuggestions ||
98 optype.includeCaseLabelSuggestions) {
99 _LabelVisitor labelVisitor = new _LabelVisitor(request,
100 optype.includeStatementLabelSuggestions,
101 optype.includeCaseLabelSuggestions);
102 labelVisitor.visit(request.target.containingNode);
103 }
104 if (optype.includeConstructorSuggestions) {
105 new _ConstructorVisitor(request).visit(request.target.containingNode);
106 }
107
108 // If target is an argument in an argument list
109 // then suggestions may need to be adjusted
110 return request.target.argIndex == null;
111 }
112
113 @override
114 Future<bool> computeFull(DartCompletionRequest request) {
115 _updateSuggestions(request);
116 return new Future.value(false);
117 }
118
119 /**
120 * If target is a function argument, suggest identifiers not invocations
121 */
122 void _updateSuggestions(DartCompletionRequest request) {
123 if (request.target.isFunctionalArgument()) {
124 request.convertInvocationsToIdentifiers();
125 }
126 }
127 }
128
129 /**
130 * A visitor for collecting constructor suggestions.
131 */
132 class _ConstructorVisitor extends LocalDeclarationVisitor {
133 final DartCompletionRequest request;
134
135 _ConstructorVisitor(DartCompletionRequest request)
136 : super(request.offset),
137 request = request;
138
139 @override
140 void declaredClass(ClassDeclaration declaration) {
141 bool found = false;
142 for (ClassMember member in declaration.members) {
143 if (member is ConstructorDeclaration) {
144 found = true;
145 _addSuggestion(declaration, member);
146 }
147 }
148 if (!found) {
149 _addSuggestion(declaration, null);
150 }
151 }
152
153 @override
154 void declaredClassTypeAlias(ClassTypeAlias declaration) {
155 // TODO: implement declaredClassTypeAlias
156 }
157
158 @override
159 void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
160 // TODO: implement declaredField
161 }
162
163 @override
164 void declaredFunction(FunctionDeclaration declaration) {
165 // TODO: implement declaredFunction
166 }
167
168 @override
169 void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
170 // TODO: implement declaredFunctionTypeAlias
171 }
172
173 @override
174 void declaredLabel(Label label, bool isCaseLabel) {
175 // TODO: implement declaredLabel
176 }
177
178 @override
179 void declaredLocalVar(SimpleIdentifier name, TypeName type) {
180 // TODO: implement declaredLocalVar
181 }
182
183 @override
184 void declaredMethod(MethodDeclaration declaration) {
185 // TODO: implement declaredMethod
186 }
187
188 @override
189 void declaredParam(SimpleIdentifier name, TypeName type) {
190 // TODO: implement declaredParam
191 }
192
193 @override
194 void declaredTopLevelVar(
195 VariableDeclarationList varList, VariableDeclaration varDecl) {
196 // TODO: implement declaredTopLevelVar
197 }
198
199 /**
200 * For the given class and constructor,
201 * add a suggestion of the form B(...) or B.name(...).
202 * If the given constructor is `null`
203 * then add a default constructor suggestion.
204 */
205 CompletionSuggestion _addSuggestion(
206 ClassDeclaration classDecl, ConstructorDeclaration constructorDecl) {
207 SimpleIdentifier elemId;
208 String completion = classDecl.name.name;
209 if (constructorDecl != null) {
210 elemId = constructorDecl.name;
211 if (elemId != null) {
212 String name = elemId.name;
213 if (name != null && name.length > 0) {
214 completion = '$completion.$name';
215 }
216 }
217 }
218 bool isDeprecated =
219 constructorDecl != null && _isDeprecated(constructorDecl);
220 List<String> parameterNames = new List<String>();
221 List<String> parameterTypes = new List<String>();
222 int requiredParameterCount = 0;
223 bool hasNamedParameters = false;
224 StringBuffer paramBuf = new StringBuffer();
225 paramBuf.write('(');
226 int paramCount = 0;
227 if (constructorDecl != null) {
228 for (FormalParameter param in constructorDecl.parameters.parameters) {
229 if (paramCount > 0) {
230 paramBuf.write(', ');
231 }
232 String paramName;
233 String typeName;
234 if (param is NormalFormalParameter) {
235 paramName = param.identifier.name;
236 typeName = _nameForParamType(param);
237 ++requiredParameterCount;
238 } else if (param is DefaultFormalParameter) {
239 NormalFormalParameter childParam = param.parameter;
240 paramName = childParam.identifier.name;
241 typeName = _nameForParamType(childParam);
242 if (param.kind == ParameterKind.NAMED) {
243 hasNamedParameters = true;
244 }
245 if (paramCount == requiredParameterCount) {
246 paramBuf.write(hasNamedParameters ? '{' : '[');
247 }
248 }
249 parameterNames.add(paramName);
250 parameterTypes.add(typeName);
251 paramBuf.write(typeName);
252 paramBuf.write(' ');
253 paramBuf.write(paramName);
254 ++paramCount;
255 }
256 }
257 if (paramCount > requiredParameterCount) {
258 paramBuf.write(hasNamedParameters ? '}' : ']');
259 }
260 paramBuf.write(')');
261 protocol.Element element = _createElement(
262 protocol.ElementKind.CONSTRUCTOR, elemId,
263 parameters: paramBuf.toString());
264 element.returnType = classDecl.name.name;
265 CompletionSuggestion suggestion = new CompletionSuggestion(
266 CompletionSuggestionKind.INVOCATION,
267 isDeprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT, completion,
268 completion.length, 0, isDeprecated, false,
269 declaringType: classDecl.name.name,
270 element: element,
271 parameterNames: parameterNames,
272 parameterTypes: parameterTypes,
273 requiredParameterCount: requiredParameterCount,
274 hasNamedParameters: hasNamedParameters);
275 request.addSuggestion(suggestion);
276 return suggestion;
277 }
278
279 /**
280 * Determine the name of the type for the given constructor parameter.
281 */
282 String _nameForParamType(NormalFormalParameter param) {
283 if (param is SimpleFormalParameter) {
284 return _nameForType(param.type);
285 }
286 SimpleIdentifier id = param.identifier;
287 if (param is FieldFormalParameter && id != null) {
288 String fieldName = id.name;
289 AstNode classDecl = param.getAncestor((p) => p is ClassDeclaration);
290 if (classDecl is ClassDeclaration) {
291 for (ClassMember member in classDecl.members) {
292 if (member is FieldDeclaration) {
293 for (VariableDeclaration field in member.fields.variables) {
294 if (field.name.name == fieldName) {
295 return _nameForType(member.fields.type);
296 }
297 }
298 }
299 }
300 }
301 }
302 return _DYNAMIC;
303 }
304 }
305
306 /**
307 * A visitor for collecting suggestions for break and continue labels.
308 */
309 class _LabelVisitor extends LocalDeclarationVisitor {
310 final DartCompletionRequest request;
311
312 /**
313 * True if statement labels should be included as suggestions.
314 */
315 final bool includeStatementLabels;
316
317 /**
318 * True if case labels should be included as suggestions.
319 */
320 final bool includeCaseLabels;
321
322 _LabelVisitor(DartCompletionRequest request, this.includeStatementLabels,
323 this.includeCaseLabels)
324 : super(request.offset),
325 request = request;
326
327 @override
328 void declaredClass(ClassDeclaration declaration) {
329 // ignored
330 }
331
332 @override
333 void declaredClassTypeAlias(ClassTypeAlias declaration) {
334 // ignored
335 }
336
337 @override
338 void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
339 // ignored
340 }
341
342 @override
343 void declaredFunction(FunctionDeclaration declaration) {
344 // ignored
345 }
346
347 @override
348 void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
349 // ignored
350 }
351
352 @override
353 void declaredLabel(Label label, bool isCaseLabel) {
354 if (isCaseLabel ? includeCaseLabels : includeStatementLabels) {
355 CompletionSuggestion suggestion = _addSuggestion(label.label);
356 if (suggestion != null) {
357 suggestion.element =
358 _createElement(protocol.ElementKind.LABEL, label.label);
359 }
360 }
361 }
362
363 @override
364 void declaredLocalVar(SimpleIdentifier name, TypeName type) {
365 // ignored
366 }
367
368 @override
369 void declaredMethod(MethodDeclaration declaration) {
370 // ignored
371 }
372
373 @override
374 void declaredParam(SimpleIdentifier name, TypeName type) {
375 // ignored
376 }
377
378 @override
379 void declaredTopLevelVar(
380 VariableDeclarationList varList, VariableDeclaration varDecl) {
381 // ignored
382 }
383
384 @override
385 void visitFunctionExpression(FunctionExpression node) {
386 // Labels are only accessible within the local function, so stop visiting
387 // once we reach a function boundary.
388 finished();
389 }
390
391 @override
392 void visitMethodDeclaration(MethodDeclaration node) {
393 // Labels are only accessible within the local function, so stop visiting
394 // once we reach a function boundary.
395 finished();
396 }
397
398 CompletionSuggestion _addSuggestion(SimpleIdentifier id) {
399 if (id != null) {
400 String completion = id.name;
401 if (completion != null && completion.length > 0 && completion != '_') {
402 CompletionSuggestion suggestion = new CompletionSuggestion(
403 CompletionSuggestionKind.IDENTIFIER, DART_RELEVANCE_DEFAULT,
404 completion, completion.length, 0, false, false);
405 request.addSuggestion(suggestion);
406 return suggestion;
407 }
408 }
409 return null;
410 }
411
412 /**
413 * Create a new protocol Element for inclusion in a completion suggestion.
414 */
415 protocol.Element _createElement(
416 protocol.ElementKind kind, SimpleIdentifier id) {
417 String name = id.name;
418 int flags =
419 protocol.Element.makeFlags(isPrivate: Identifier.isPrivateName(name));
420 return new protocol.Element(kind, name, flags);
421 }
422 }
423
424 /**
425 * A visitor for collecting suggestions from the most specific child [AstNode]
426 * that contains the completion offset to the [CompilationUnit].
427 */
428 class _LocalVisitor extends LocalDeclarationVisitor {
429 final DartCompletionRequest request;
430 final OpType optype;
431
432 _LocalVisitor(this.request, int offset, this.optype) : super(offset);
433
434 @override
435 void declaredClass(ClassDeclaration declaration) {
436 if (optype.includeTypeNameSuggestions) {
437 bool isDeprecated = _isDeprecated(declaration);
438 CompletionSuggestion suggestion = _addSuggestion(declaration.name,
439 _NO_RETURN_TYPE, isDeprecated, DART_RELEVANCE_DEFAULT);
440 if (suggestion != null) {
441 suggestion.element = _createElement(
442 protocol.ElementKind.CLASS, declaration.name,
443 returnType: _NO_RETURN_TYPE,
444 isAbstract: declaration.isAbstract,
445 isDeprecated: isDeprecated);
446 }
447 }
448 }
449
450 @override
451 void declaredClassTypeAlias(ClassTypeAlias declaration) {
452 if (optype.includeTypeNameSuggestions) {
453 bool isDeprecated = _isDeprecated(declaration);
454 CompletionSuggestion suggestion = _addSuggestion(declaration.name,
455 _NO_RETURN_TYPE, isDeprecated, DART_RELEVANCE_DEFAULT);
456 if (suggestion != null) {
457 suggestion.element = _createElement(
458 protocol.ElementKind.CLASS_TYPE_ALIAS, declaration.name,
459 returnType: _NO_RETURN_TYPE,
460 isAbstract: true,
461 isDeprecated: isDeprecated);
462 }
463 }
464 }
465
466 @override
467 void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
468 if (optype.includeReturnValueSuggestions) {
469 bool isDeprecated = _isDeprecated(fieldDecl) || _isDeprecated(varDecl);
470 TypeName type = fieldDecl.fields.type;
471 CompletionSuggestion suggestion = _addSuggestion(
472 varDecl.name, type, isDeprecated, DART_RELEVANCE_LOCAL_FIELD,
473 classDecl: fieldDecl.parent);
474 if (suggestion != null) {
475 suggestion.element = _createElement(
476 protocol.ElementKind.FIELD, varDecl.name,
477 returnType: type, isDeprecated: isDeprecated);
478 }
479 }
480 }
481
482 @override
483 void declaredFunction(FunctionDeclaration declaration) {
484 if (optype.includeReturnValueSuggestions ||
485 optype.includeVoidReturnSuggestions) {
486 TypeName returnType = declaration.returnType;
487 bool isDeprecated = _isDeprecated(declaration);
488 protocol.ElementKind kind;
489 int defaultRelevance = DART_RELEVANCE_DEFAULT;
490 if (declaration.isGetter) {
491 kind = protocol.ElementKind.GETTER;
492 defaultRelevance = DART_RELEVANCE_LOCAL_ACCESSOR;
493 } else if (declaration.isSetter) {
494 if (!optype.includeVoidReturnSuggestions) {
495 return;
496 }
497 kind = protocol.ElementKind.SETTER;
498 returnType = _NO_RETURN_TYPE;
499 defaultRelevance = DART_RELEVANCE_LOCAL_ACCESSOR;
500 } else {
501 if (!optype.includeVoidReturnSuggestions && _isVoid(returnType)) {
502 return;
503 }
504 kind = protocol.ElementKind.FUNCTION;
505 defaultRelevance = DART_RELEVANCE_LOCAL_FUNCTION;
506 }
507 CompletionSuggestion suggestion = _addSuggestion(
508 declaration.name, returnType, isDeprecated, defaultRelevance);
509 if (suggestion != null) {
510 FormalParameterList param = declaration.functionExpression.parameters;
511 suggestion.element = _createElement(kind, declaration.name,
512 parameters: param != null ? param.toSource() : null,
513 returnType: returnType,
514 isDeprecated: isDeprecated);
515 if (kind == protocol.ElementKind.FUNCTION) {
516 _addParameterInfo(
517 suggestion, declaration.functionExpression.parameters);
518 }
519 }
520 }
521 }
522
523 @override
524 void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
525 if (optype.includeTypeNameSuggestions) {
526 bool isDeprecated = _isDeprecated(declaration);
527 TypeName returnType = declaration.returnType;
528 CompletionSuggestion suggestion = _addSuggestion(
529 declaration.name, returnType, isDeprecated, DART_RELEVANCE_DEFAULT);
530 if (suggestion != null) {
531 // TODO (danrubel) determine parameters and return type
532 suggestion.element = _createElement(
533 protocol.ElementKind.FUNCTION_TYPE_ALIAS, declaration.name,
534 returnType: returnType,
535 isAbstract: true,
536 isDeprecated: isDeprecated);
537 }
538 }
539 }
540
541 @override
542 void declaredLabel(Label label, bool isCaseLabel) {
543 // ignored
544 }
545
546 @override
547 void declaredLocalVar(SimpleIdentifier name, TypeName type) {
548 if (optype.includeReturnValueSuggestions) {
549 CompletionSuggestion suggestion =
550 _addSuggestion(name, type, false, DART_RELEVANCE_LOCAL_VARIABLE);
551 if (suggestion != null) {
552 suggestion.element = _createElement(
553 protocol.ElementKind.LOCAL_VARIABLE, name, returnType: type);
554 }
555 }
556 }
557
558 @override
559 void declaredMethod(MethodDeclaration declaration) {
560 if (optype.includeReturnValueSuggestions ||
561 optype.includeVoidReturnSuggestions) {
562 protocol.ElementKind kind;
563 String parameters;
564 TypeName returnType = declaration.returnType;
565 int defaultRelevance = DART_RELEVANCE_DEFAULT;
566 if (declaration.isGetter) {
567 kind = protocol.ElementKind.GETTER;
568 parameters = null;
569 defaultRelevance = DART_RELEVANCE_LOCAL_ACCESSOR;
570 } else if (declaration.isSetter) {
571 if (!optype.includeVoidReturnSuggestions) {
572 return;
573 }
574 kind = protocol.ElementKind.SETTER;
575 returnType = _NO_RETURN_TYPE;
576 defaultRelevance = DART_RELEVANCE_LOCAL_ACCESSOR;
577 } else {
578 if (!optype.includeVoidReturnSuggestions && _isVoid(returnType)) {
579 return;
580 }
581 kind = protocol.ElementKind.METHOD;
582 parameters = declaration.parameters.toSource();
583 defaultRelevance = DART_RELEVANCE_LOCAL_METHOD;
584 }
585 bool isDeprecated = _isDeprecated(declaration);
586 CompletionSuggestion suggestion = _addSuggestion(
587 declaration.name, returnType, isDeprecated, defaultRelevance,
588 classDecl: declaration.parent);
589 if (suggestion != null) {
590 suggestion.element = _createElement(kind, declaration.name,
591 parameters: parameters,
592 returnType: returnType,
593 isAbstract: declaration.isAbstract,
594 isDeprecated: isDeprecated);
595 if (kind == protocol.ElementKind.METHOD) {
596 _addParameterInfo(suggestion, declaration.parameters);
597 }
598 }
599 }
600 }
601
602 @override
603 void declaredParam(SimpleIdentifier name, TypeName type) {
604 if (optype.includeReturnValueSuggestions) {
605 CompletionSuggestion suggestion =
606 _addSuggestion(name, type, false, DART_RELEVANCE_PARAMETER);
607 if (suggestion != null) {
608 suggestion.element = _createElement(
609 protocol.ElementKind.PARAMETER, name, returnType: type);
610 }
611 }
612 }
613
614 @override
615 void declaredTopLevelVar(
616 VariableDeclarationList varList, VariableDeclaration varDecl) {
617 if (optype.includeReturnValueSuggestions) {
618 bool isDeprecated = _isDeprecated(varList) || _isDeprecated(varDecl);
619 CompletionSuggestion suggestion = _addSuggestion(varDecl.name,
620 varList.type, isDeprecated, DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
621 if (suggestion != null) {
622 suggestion.element = _createElement(
623 protocol.ElementKind.TOP_LEVEL_VARIABLE, varDecl.name,
624 returnType: varList.type, isDeprecated: isDeprecated);
625 }
626 }
627 }
628
629 void _addParameterInfo(
630 CompletionSuggestion suggestion, FormalParameterList parameters) {
631 var paramList = parameters.parameters;
632 suggestion.parameterNames = paramList
633 .map((FormalParameter param) => param.identifier.name)
634 .toList();
635 suggestion.parameterTypes = paramList.map((FormalParameter param) {
636 TypeName type = null;
637 if (param is DefaultFormalParameter) {
638 NormalFormalParameter child = param.parameter;
639 if (child is SimpleFormalParameter) {
640 type = child.type;
641 } else if (child is FieldFormalParameter) {
642 type = child.type;
643 }
644 }
645 if (param is SimpleFormalParameter) {
646 type = param.type;
647 } else if (param is FieldFormalParameter) {
648 type = param.type;
649 }
650 if (type == null) {
651 return 'dynamic';
652 }
653 Identifier typeId = type.name;
654 if (typeId == null) {
655 return 'dynamic';
656 }
657 return typeId.name;
658 }).toList();
659 suggestion.requiredParameterCount = paramList.where(
660 (FormalParameter param) => param is! DefaultFormalParameter).length;
661 suggestion.hasNamedParameters = paramList
662 .any((FormalParameter param) => param.kind == ParameterKind.NAMED);
663 }
664
665 CompletionSuggestion _addSuggestion(SimpleIdentifier id, TypeName returnType,
666 bool isDeprecated, int defaultRelevance, {ClassDeclaration classDecl}) {
667 if (id != null) {
668 String completion = id.name;
669 if (completion != null && completion.length > 0 && completion != '_') {
670 CompletionSuggestion suggestion = new CompletionSuggestion(
671 CompletionSuggestionKind.INVOCATION,
672 isDeprecated ? DART_RELEVANCE_LOW : defaultRelevance, completion,
673 completion.length, 0, isDeprecated, false,
674 returnType: _nameForType(returnType));
675 if (classDecl != null) {
676 SimpleIdentifier identifier = classDecl.name;
677 if (identifier != null) {
678 String name = identifier.name;
679 if (name != null && name.length > 0) {
680 suggestion.declaringType = name;
681 }
682 }
683 }
684 request.addSuggestion(suggestion);
685 return suggestion;
686 }
687 }
688 return null;
689 }
690
691 bool _isVoid(TypeName returnType) {
692 if (returnType != null) {
693 Identifier id = returnType.name;
694 if (id != null && id.name == 'void') {
695 return true;
696 }
697 }
698 return false;
699 }
700 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698