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

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

Issue 1410893002: Disable completion in comment text. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 library analysis_server.src.provisional.completion.dart.completion_target; 5 library analysis_server.src.provisional.completion.dart.completion_target;
6 6
7 import 'package:analyzer/src/generated/ast.dart'; 7 import 'package:analyzer/src/generated/ast.dart';
8 import 'package:analyzer/src/generated/element.dart'; 8 import 'package:analyzer/src/generated/element.dart';
9 import 'package:analyzer/src/generated/scanner.dart'; 9 import 'package:analyzer/src/generated/scanner.dart';
10 import 'package:analyzer/src/generated/utilities_dart.dart'; 10 import 'package:analyzer/src/generated/utilities_dart.dart';
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 * 96 *
97 * Usually, the entity won't be the first child of the [containingNode] (this 97 * Usually, the entity won't be the first child of the [containingNode] (this
98 * is a consequence of placing the completion target as high in the tree as 98 * is a consequence of placing the completion target as high in the tree as
99 * possible). However, there is one exception: when the cursor is inside of 99 * possible). However, there is one exception: when the cursor is inside of
100 * a multi-character token which is not a keyword or identifier (e.g. a 100 * a multi-character token which is not a keyword or identifier (e.g. a
101 * comment, or a token like "+=", the entity will be always be the token. 101 * comment, or a token like "+=", the entity will be always be the token.
102 */ 102 */
103 final Object entity; 103 final Object entity;
104 104
105 /** 105 /**
106 * The [entity] is a comment token, which is either not a documentation
107 * comment or the position is not in a [CommentReference].
108 */
109 final bool isCommentText;
110
111 /**
106 * If the target is an argument in an [ArgumentList], then this is the index 112 * If the target is an argument in an [ArgumentList], then this is the index
107 * of the argument in the list, otherwise this is `null`. 113 * of the argument in the list, otherwise this is `null`.
108 */ 114 */
109 final int argIndex; 115 final int argIndex;
110 116
111 /** 117 /**
112 * Compute the appropriate [CompletionTarget] for the given [offset] within 118 * Compute the appropriate [CompletionTarget] for the given [offset] within
113 * the [compilationUnit]. 119 * the [compilationUnit].
114 */ 120 */
115 factory CompletionTarget.forOffset( 121 factory CompletionTarget.forOffset(
(...skipping 22 matching lines...) Expand all
138 if (commentReference.offset <= offset && 144 if (commentReference.offset <= offset &&
139 offset <= commentReference.end) { 145 offset <= commentReference.end) {
140 containingNode = commentReference; 146 containingNode = commentReference;
141 continue outerLoop; 147 continue outerLoop;
142 } 148 }
143 } 149 }
144 } 150 }
145 for (var entity in containingNode.childEntities) { 151 for (var entity in containingNode.childEntities) {
146 if (entity is Token) { 152 if (entity is Token) {
147 if (_isCandidateToken(entity, offset)) { 153 if (_isCandidateToken(entity, offset)) {
154 // Try to replace with a comment token.
155 Token commentToken = _getContainingCommentToken(entity, offset);
156 if (commentToken != null) {
157 return new CompletionTarget._(containingNode, commentToken, true);
158 }
148 // Target found. 159 // Target found.
149 return new CompletionTarget._(containingNode, entity); 160 return new CompletionTarget._(containingNode, entity, false);
150 } else { 161 } else {
151 // Since entity is a token, we don't need to look inside it; just 162 // Since entity is a token, we don't need to look inside it; just
152 // proceed to the next entity. 163 // proceed to the next entity.
153 continue; 164 continue;
154 } 165 }
155 } else if (entity is AstNode) { 166 } else if (entity is AstNode) {
156 // If the last token in the node isn't a candidate target, then 167 // If the last token in the node isn't a candidate target, then
157 // neither the node nor any of its descendants can possibly be the 168 // neither the node nor any of its descendants can possibly be the
158 // completion target, so we can skip the node entirely. 169 // completion target, so we can skip the node entirely.
159 if (!_isCandidateToken(entity.endToken, offset)) { 170 if (!_isCandidateToken(entity.endToken, offset)) {
160 continue; 171 continue;
161 } 172 }
162 173
163 // If the node is a candidate target, then we are done. 174 // If the node is a candidate target, then we are done.
164 if (_isCandidateNode(entity, offset)) { 175 if (_isCandidateNode(entity, offset)) {
165 // Check to see if the offset is in a preceeding comment 176 // Check to see if the offset is in a preceding comment
166 Token commentToken = _getContainingCommentToken(entity, offset); 177 Token commentToken =
178 _getContainingCommentToken(entity.beginToken, offset);
167 if (commentToken != null) { 179 if (commentToken != null) {
168 entity = commentToken; 180 entity = commentToken;
169 // If the preceeding comment is dartdoc token then update 181 // If the preceding comment is dartdoc token, then update
170 // the containing node to be the dartdoc comment 182 // the containing node to be the dartdoc comment.
183 // Otherwise completion is not required.
171 Comment docComment = 184 Comment docComment =
172 _getContainingDocComment(containingNode, commentToken); 185 _getContainingDocComment(containingNode, commentToken);
173 if (docComment != null) { 186 if (docComment != null) {
174 containingNode = docComment; 187 containingNode = docComment;
188 } else {
189 return new CompletionTarget._(
190 compilationUnit, commentToken, true);
175 } 191 }
176 } 192 }
177 return new CompletionTarget._(containingNode, entity); 193 return new CompletionTarget._(containingNode, entity, false);
178 } 194 }
179 195
180 // Otherwise, the completion target is somewhere inside the entity, 196 // Otherwise, the completion target is somewhere inside the entity,
181 // so we need to jump to the start of the outer loop to examine its 197 // so we need to jump to the start of the outer loop to examine its
182 // contents. 198 // contents.
183 containingNode = entity; 199 containingNode = entity;
184 continue outerLoop; 200 continue outerLoop;
185 } else { 201 } else {
186 // Unexpected entity found (all entities in a parse tree should be 202 // Unexpected entity found (all entities in a parse tree should be
187 // AST nodes or tokens). 203 // AST nodes or tokens).
188 assert(false); 204 assert(false);
189 } 205 }
190 } 206 }
191 207
192 // No completion target found. It should only be possible to reach here 208 // No completion target found. It should only be possible to reach here
193 // the first time through the outer loop (since we only jump to the start 209 // the first time through the outer loop (since we only jump to the start
194 // of the outer loop after determining that the completion target is 210 // of the outer loop after determining that the completion target is
195 // inside an entity). We can check that assumption by verifying that 211 // inside an entity). We can check that assumption by verifying that
196 // containingNode is still the compilationUnit. 212 // containingNode is still the compilationUnit.
197 assert(identical(containingNode, compilationUnit)); 213 assert(identical(containingNode, compilationUnit));
198 214
199 // Since no completion target was found, we set the completion target 215 // Since no completion target was found, we set the completion target
200 // entity to null and use the compilationUnit as the parent. 216 // entity to null and use the compilationUnit as the parent.
201 return new CompletionTarget._(compilationUnit, null); 217 return new CompletionTarget._(compilationUnit, null, false);
202 } 218 }
203 } 219 }
204 220
205 /** 221 /**
206 * Create a [CompletionTarget] holding the given [containingNode] and 222 * Create a [CompletionTarget] holding the given [containingNode] and
207 * [entity]. 223 * [entity].
208 */ 224 */
209 CompletionTarget._(AstNode containingNode, Object entity) 225 CompletionTarget._(AstNode containingNode, Object entity, this.isCommentText)
210 : this.containingNode = containingNode, 226 : this.containingNode = containingNode,
211 this.entity = entity, 227 this.entity = entity,
212 this.argIndex = _computeArgIndex(containingNode, entity); 228 this.argIndex = _computeArgIndex(containingNode, entity);
213 229
214 /** 230 /**
215 * Return `true` if the target is a functional argument in an argument list. 231 * Return `true` if the target is a functional argument in an argument list.
216 * The target [AstNode] hierarchy *must* be resolved for this to work. 232 * The target [AstNode] hierarchy *must* be resolved for this to work.
217 */ 233 */
218 bool isFunctionalArgument() { 234 bool isFunctionalArgument() {
219 if (argIndex == null) { 235 if (argIndex == null) {
(...skipping 25 matching lines...) Expand all
245 return _isFunctionalParameter(methodElem.parameters, argIndex); 261 return _isFunctionalParameter(methodElem.parameters, argIndex);
246 } else if (methodElem is FunctionElement) { 262 } else if (methodElem is FunctionElement) {
247 return _isFunctionalParameter(methodElem.parameters, argIndex); 263 return _isFunctionalParameter(methodElem.parameters, argIndex);
248 } 264 }
249 } 265 }
250 } 266 }
251 return false; 267 return false;
252 } 268 }
253 269
254 /** 270 /**
255 * Determine if the offset is contained in a preceeding comment token 271 * Determine if the offset is contained in a preceding comment token
256 * and return that token, otherwise return `null`. 272 * and return that token, otherwise return `null`.
257 */ 273 */
258 static Token _getContainingCommentToken(AstNode node, int offset) { 274 static Token _getContainingCommentToken(Token token, int offset) {
259 if (offset >= node.offset) {
260 return null;
261 }
262 Token token = node.beginToken;
263 if (token == null) { 275 if (token == null) {
264 return null; 276 return null;
265 } 277 }
278 if (offset >= token.offset) {
279 return null;
280 }
266 token = token.precedingComments; 281 token = token.precedingComments;
267 while (token != null) { 282 while (token != null) {
268 if (offset <= token.offset) { 283 if (offset <= token.offset) {
269 return null; 284 return null;
270 } 285 }
271 if (offset <= token.end) { 286 if (offset <= token.end) {
272 if (token.type == TokenType.SINGLE_LINE_COMMENT || offset < token.end) { 287 if (token.type == TokenType.SINGLE_LINE_COMMENT || offset < token.end) {
273 return token; 288 return token;
274 } 289 }
275 } 290 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 if (param.parameterKind == ParameterKind.NAMED) { 368 if (param.parameterKind == ParameterKind.NAMED) {
354 // TODO(danrubel) handle named parameters 369 // TODO(danrubel) handle named parameters
355 return false; 370 return false;
356 } else { 371 } else {
357 return paramType is FunctionType || paramType is FunctionTypeAlias; 372 return paramType is FunctionType || paramType is FunctionTypeAlias;
358 } 373 }
359 } 374 }
360 return false; 375 return false;
361 } 376 }
362 } 377 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698