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

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

Issue 985183003: fix completion target handling of comments (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: merge Created 5 years, 9 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
« no previous file with comments | « no previous file | pkg/analysis_server/test/services/completion/completion_target_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 import 'package:analyzer/src/generated/ast.dart'; 1 import 'package:analyzer/src/generated/ast.dart';
2 import 'package:analyzer/src/generated/element.dart'; 2 import 'package:analyzer/src/generated/element.dart';
3 import 'package:analyzer/src/generated/scanner.dart'; 3 import 'package:analyzer/src/generated/scanner.dart';
4 import 'package:analyzer/src/generated/utilities_dart.dart'; 4 import 'package:analyzer/src/generated/utilities_dart.dart';
5 5
6 int _computeArgIndex(AstNode containingNode, Object entity) { 6 int _computeArgIndex(AstNode containingNode, Object entity) {
7 var argList = containingNode; 7 var argList = containingNode;
8 if (argList is ArgumentList) { 8 if (argList is ArgumentList) {
9 NodeList<Expression> args = argList.arguments; 9 NodeList<Expression> args = argList.arguments;
10 for (int index = 0; index < args.length; ++index) { 10 for (int index = 0; index < args.length; ++index) {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 } else if (entity is AstNode) { 149 } else if (entity is AstNode) {
150 // If the last token in the node isn't a candidate target, then 150 // If the last token in the node isn't a candidate target, then
151 // neither the node nor any of its descendants can possibly be the 151 // neither the node nor any of its descendants can possibly be the
152 // completion target, so we can skip the node entirely. 152 // completion target, so we can skip the node entirely.
153 if (!_isCandidateToken(entity.endToken, offset)) { 153 if (!_isCandidateToken(entity.endToken, offset)) {
154 continue; 154 continue;
155 } 155 }
156 156
157 // If the node is a candidate target, then we are done. 157 // If the node is a candidate target, then we are done.
158 if (_isCandidateNode(entity, offset)) { 158 if (_isCandidateNode(entity, offset)) {
159 // Check to see if the offset is in a preceeding comment
160 Token commentToken = _getContainingCommentToken(entity, offset);
161 if (commentToken != null) {
162 entity = commentToken;
163 // If the preceeding comment is dartdoc token then update
164 // the containing node to be the dartdoc comment
165 Comment docComment =
166 _getContainingDocComment(containingNode, commentToken);
167 if (docComment != null) {
168 containingNode = docComment;
169 }
170 }
159 return new CompletionTarget._(containingNode, entity); 171 return new CompletionTarget._(containingNode, entity);
160 } 172 }
161 173
162 // Otherwise, the completion target is somewhere inside the entity, 174 // Otherwise, the completion target is somewhere inside the entity,
163 // so we need to jump to the start of the outer loop to examine its 175 // so we need to jump to the start of the outer loop to examine its
164 // contents. 176 // contents.
165 containingNode = entity; 177 containingNode = entity;
166 continue outerLoop; 178 continue outerLoop;
167 } else { 179 } else {
168 // Unexpected entity found (all entities in a parse tree should be 180 // Unexpected entity found (all entities in a parse tree should be
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 return _isFunctionalParameter(methodElem.parameters, argIndex); 239 return _isFunctionalParameter(methodElem.parameters, argIndex);
228 } else if (methodElem is FunctionElement) { 240 } else if (methodElem is FunctionElement) {
229 return _isFunctionalParameter(methodElem.parameters, argIndex); 241 return _isFunctionalParameter(methodElem.parameters, argIndex);
230 } 242 }
231 } 243 }
232 } 244 }
233 return false; 245 return false;
234 } 246 }
235 247
236 /** 248 /**
249 * Determine if the offset is contained in a preceeding comment token
250 * and return that token, otherwise return `null`.
251 */
252 static Token _getContainingCommentToken(AstNode node, int offset) {
253 if (offset >= node.offset) {
254 return null;
255 }
256 Token token = node.beginToken;
257 if (token == null) {
258 return null;
259 }
260 token = token.precedingComments;
261 while (token != null) {
262 if (offset <= token.offset) {
263 return null;
264 }
265 if (offset <= token.end) {
266 if (token.type == TokenType.SINGLE_LINE_COMMENT || offset < token.end) {
267 return token;
268 }
269 }
270 token = token.next;
271 }
272 return null;
273 }
274
275 /**
276 * Determine if the given token is part of the given node's dart doc.
277 */
278 static Comment _getContainingDocComment(AstNode node, Token token) {
279 if (node is AnnotatedNode) {
280 Comment docComment = node.documentationComment;
281 if (docComment != null && docComment.tokens.contains(token)) {
282 return docComment;
283 }
284 }
285 return null;
286 }
287
288 /**
237 * Determine whether [node] could possibly be the [entity] for a 289 * Determine whether [node] could possibly be the [entity] for a
238 * [CompletionTarget] associated with the given [offset]. 290 * [CompletionTarget] associated with the given [offset].
239 */ 291 */
240 static bool _isCandidateNode(AstNode node, int offset) { 292 static bool _isCandidateNode(AstNode node, int offset) {
241 // If the node's first token is a keyword or identifier, then the node is a 293 // If the node's first token is a keyword or identifier, then the node is a
242 // candidate entity if its first token is. 294 // candidate entity if its first token is.
243 Token beginToken = node.beginToken; 295 Token beginToken = node.beginToken;
244 if (beginToken.type == TokenType.KEYWORD || 296 if (beginToken.type == TokenType.KEYWORD ||
245 beginToken.type == TokenType.IDENTIFIER) { 297 beginToken.type == TokenType.IDENTIFIER) {
246 return _isCandidateToken(beginToken, offset); 298 return _isCandidateToken(beginToken, offset);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 if (param.parameterKind == ParameterKind.NAMED) { 336 if (param.parameterKind == ParameterKind.NAMED) {
285 // TODO(danrubel) handle named parameters 337 // TODO(danrubel) handle named parameters
286 return false; 338 return false;
287 } else { 339 } else {
288 return paramType is FunctionType || paramType is FunctionTypeAlias; 340 return paramType is FunctionType || paramType is FunctionTypeAlias;
289 } 341 }
290 } 342 }
291 return false; 343 return false;
292 } 344 }
293 } 345 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/test/services/completion/completion_target_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698