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

Side by Side Diff: pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart

Issue 2946573003: Remove ReplacementRange (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analyzer_plugin/lib/utilities/completion/replacement_range.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 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'package:analyzer/dart/ast/ast.dart'; 5 import 'package:analyzer/dart/ast/ast.dart';
6 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
6 import 'package:analyzer/dart/ast/token.dart'; 7 import 'package:analyzer/dart/ast/token.dart';
7 import 'package:analyzer/dart/element/element.dart'; 8 import 'package:analyzer/dart/element/element.dart';
8 import 'package:analyzer/dart/element/type.dart'; 9 import 'package:analyzer/dart/element/type.dart';
10 import 'package:analyzer/src/dart/ast/token.dart';
11 import 'package:analyzer/src/generated/source.dart';
9 import 'package:analyzer/src/generated/utilities_dart.dart'; 12 import 'package:analyzer/src/generated/utilities_dart.dart';
10 13
11 /** 14 /**
12 * A CompletionTarget represents an edge in the parse tree which connects an 15 * A CompletionTarget represents an edge in the parse tree which connects an
13 * AST node (the [containingNode] of the completion) to one of its children 16 * AST node (the [containingNode] of the completion) to one of its children
14 * (the [entity], which represents the place in the parse tree where the newly 17 * (the [entity], which represents the place in the parse tree where the newly
15 * completed text will be inserted). 18 * completed text will be inserted).
16 * 19 *
17 * To illustrate, consider the following snippet of code, and its associated 20 * To illustrate, consider the following snippet of code, and its associated
18 * parse tree. (T's represent tokens, N's represent AST nodes. Some trivial 21 * parse tree. (T's represent tokens, N's represent AST nodes. Some trivial
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 if (node is PropertyAccess) { 248 if (node is PropertyAccess) {
246 return node.isCascaded && offset > node.operator.offset + 1; 249 return node.isCascaded && offset > node.operator.offset + 1;
247 } 250 }
248 if (node is MethodInvocation) { 251 if (node is MethodInvocation) {
249 return node.isCascaded && offset > node.operator.offset + 1; 252 return node.isCascaded && offset > node.operator.offset + 1;
250 } 253 }
251 return false; 254 return false;
252 } 255 }
253 256
254 /** 257 /**
258 * Return a source range that represents the region of text that should be
259 * replaced when a suggestion based on this target is selected, given that the
260 * completion was requested at the given [requestOffset].
261 */
262 SourceRange computeReplacementRange(int requestOffset) {
263 bool isKeywordOrIdentifier(Token token) =>
264 token.type.isKeyword || token.type == TokenType.IDENTIFIER;
265
266 Token token = entity is AstNode ? (entity as AstNode).beginToken : entity;
267 if (token != null && requestOffset < token.offset) {
268 token = token.previous;
269 }
270 if (token != null) {
271 if (requestOffset == token.offset && !isKeywordOrIdentifier(token)) {
272 // If the insertion point is at the beginning of the current token
273 // and the current token is not an identifier
274 // then check the previous token to see if it should be replaced
275 token = token.previous;
276 }
277 if (token != null && isKeywordOrIdentifier(token)) {
278 if (token.offset <= requestOffset && requestOffset <= token.end) {
279 // Replacement range for typical identifier completion
280 return new SourceRange(token.offset, token.length);
281 }
282 }
283 if (token is StringToken) {
284 SimpleStringLiteral uri =
285 astFactory.simpleStringLiteral(token, token.lexeme);
286 Keyword keyword = token.previous?.keyword;
287 if (keyword == Keyword.IMPORT ||
288 keyword == Keyword.EXPORT ||
289 keyword == Keyword.PART) {
290 int start = uri.contentsOffset;
291 int end = uri.contentsEnd;
292 if (start <= requestOffset && requestOffset <= end) {
293 // Replacement range for import URI
294 return new SourceRange(start, end - start);
295 }
296 }
297 }
298 }
299 return new SourceRange(requestOffset, 0);
300 }
301
302 /**
255 * Return `true` if the target is a functional argument in an argument list. 303 * Return `true` if the target is a functional argument in an argument list.
256 * The target [AstNode] hierarchy *must* be resolved for this to work. 304 * The target [AstNode] hierarchy *must* be resolved for this to work.
257 * See [maybeFunctionalArgument]. 305 * See [maybeFunctionalArgument].
258 */ 306 */
259 bool isFunctionalArgument() { 307 bool isFunctionalArgument() {
260 if (!maybeFunctionalArgument()) { 308 if (!maybeFunctionalArgument()) {
261 return false; 309 return false;
262 } 310 }
263 AstNode parent = containingNode.parent; 311 AstNode parent = containingNode.parent;
264 if (parent is ArgumentList) { 312 if (parent is ArgumentList) {
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 orElse: () => null); 494 orElse: () => null);
447 paramType = param?.type; 495 paramType = param?.type;
448 } 496 }
449 } else { 497 } else {
450 paramType = param.type; 498 paramType = param.type;
451 } 499 }
452 } 500 }
453 return paramType is FunctionType || paramType is FunctionTypeAlias; 501 return paramType is FunctionType || paramType is FunctionTypeAlias;
454 } 502 }
455 } 503 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer_plugin/lib/utilities/completion/replacement_range.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698