Disable completion in comment text.

It drives me nuts when I try to type some text and IDEA replaces my words with some random identifies.

R=brianwilkerson@google.com, danrubel@google.com
BUG=

Review URL: https://codereview.chromium.org/1410893002 .
This commit is contained in:
Konstantin Shcheglov 2015-10-16 10:38:47 -07:00
parent f80d85dee0
commit ce6614f2dc
7 changed files with 109 additions and 19 deletions

View file

@ -102,6 +102,12 @@ class CompletionTarget {
*/
final Object entity;
/**
* The [entity] is a comment token, which is either not a documentation
* comment or the position is not in a [CommentReference].
*/
final bool isCommentText;
/**
* If the target is an argument in an [ArgumentList], then this is the index
* of the argument in the list, otherwise this is `null`.
@ -145,8 +151,13 @@ class CompletionTarget {
for (var entity in containingNode.childEntities) {
if (entity is Token) {
if (_isCandidateToken(entity, offset)) {
// Try to replace with a comment token.
Token commentToken = _getContainingCommentToken(entity, offset);
if (commentToken != null) {
return new CompletionTarget._(containingNode, commentToken, true);
}
// Target found.
return new CompletionTarget._(containingNode, entity);
return new CompletionTarget._(containingNode, entity, false);
} else {
// Since entity is a token, we don't need to look inside it; just
// proceed to the next entity.
@ -162,19 +173,24 @@ class CompletionTarget {
// If the node is a candidate target, then we are done.
if (_isCandidateNode(entity, offset)) {
// Check to see if the offset is in a preceeding comment
Token commentToken = _getContainingCommentToken(entity, offset);
// Check to see if the offset is in a preceding comment
Token commentToken =
_getContainingCommentToken(entity.beginToken, offset);
if (commentToken != null) {
entity = commentToken;
// If the preceeding comment is dartdoc token then update
// the containing node to be the dartdoc comment
// If the preceding comment is dartdoc token, then update
// the containing node to be the dartdoc comment.
// Otherwise completion is not required.
Comment docComment =
_getContainingDocComment(containingNode, commentToken);
if (docComment != null) {
containingNode = docComment;
} else {
return new CompletionTarget._(
compilationUnit, commentToken, true);
}
}
return new CompletionTarget._(containingNode, entity);
return new CompletionTarget._(containingNode, entity, false);
}
// Otherwise, the completion target is somewhere inside the entity,
@ -198,7 +214,7 @@ class CompletionTarget {
// Since no completion target was found, we set the completion target
// entity to null and use the compilationUnit as the parent.
return new CompletionTarget._(compilationUnit, null);
return new CompletionTarget._(compilationUnit, null, false);
}
}
@ -206,7 +222,7 @@ class CompletionTarget {
* Create a [CompletionTarget] holding the given [containingNode] and
* [entity].
*/
CompletionTarget._(AstNode containingNode, Object entity)
CompletionTarget._(AstNode containingNode, Object entity, this.isCommentText)
: this.containingNode = containingNode,
this.entity = entity,
this.argIndex = _computeArgIndex(containingNode, entity);
@ -252,15 +268,14 @@ class CompletionTarget {
}
/**
* Determine if the offset is contained in a preceeding comment token
* Determine if the offset is contained in a preceding comment token
* and return that token, otherwise return `null`.
*/
static Token _getContainingCommentToken(AstNode node, int offset) {
if (offset >= node.offset) {
static Token _getContainingCommentToken(Token token, int offset) {
if (token == null) {
return null;
}
Token token = node.beginToken;
if (token == null) {
if (offset >= token.offset) {
return null;
}
token = token.precedingComments;

View file

@ -30,6 +30,11 @@ class ImportedReferenceContributor extends DartCompletionContributor {
@override
bool computeFast(DartCompletionRequest request) {
// Don't suggest in comments.
if (request.target.isCommentText) {
return true;
}
OpType optype = request.optype;
if (!optype.isPrefixed) {
if (optype.includeReturnValueSuggestions ||

View file

@ -22,7 +22,9 @@ const AWAIT = 'await';
class KeywordContributor extends DartCompletionContributor {
@override
bool computeFast(DartCompletionRequest request) {
request.target.containingNode.accept(new _KeywordVisitor(request));
if (!request.target.isCommentText) {
request.target.containingNode.accept(new _KeywordVisitor(request));
}
return true;
}
@ -33,7 +35,7 @@ class KeywordContributor extends DartCompletionContributor {
}
/**
* A vistor for generating keyword suggestions.
* A visitor for generating keyword suggestions.
*/
class _KeywordVisitor extends GeneralizingAstVisitor {
final DartCompletionRequest request;
@ -176,9 +178,9 @@ class _KeywordVisitor extends GeneralizingAstVisitor {
@override
visitFormalParameterList(FormalParameterList node) {
AstNode constructorDecl =
AstNode constructorDeclaration =
node.getAncestor((p) => p is ConstructorDeclaration);
if (constructorDecl != null) {
if (constructorDeclaration != null) {
_addSuggestions([Keyword.THIS]);
}
}

View file

@ -24,6 +24,11 @@ import 'package:analyzer/src/generated/utilities_dart.dart';
class LocalReferenceContributor extends DartCompletionContributor {
@override
bool computeFast(DartCompletionRequest request) {
// Don't suggest in comments.
if (request.target.isCommentText) {
return true;
}
OpType optype = request.optype;
// Collect suggestions from the specific child [AstNode] that contains

View file

@ -490,6 +490,17 @@ class B extends A {
});
}
test_inComment_endOfLine() {
addTestSource('''
main() {
// text ^
}
''');
return computeFull((bool result) {
assertNoSuggestions();
});
}
test_InstanceCreationExpression() {
addSource(
'/testA.dart',

View file

@ -436,8 +436,7 @@ class KeywordContributorTest extends AbstractCompletionTest {
var keywords = <Keyword>[];
keywords.addAll(STMT_START_OUTSIDE_CLASS);
keywords.add(Keyword.RETHROW);
assertSuggestKeywords(keywords,
relevance: DART_RELEVANCE_KEYWORD);
assertSuggestKeywords(keywords, relevance: DART_RELEVANCE_KEYWORD);
}
test_class() {
@ -1036,6 +1035,27 @@ class A {
expect(request.replacementLength, 3);
}
test_inComment_block() {
addTestSource('''
main() {
/* text ^ */
print(42);
}
''');
expect(computeFast(), isTrue);
assertNoSuggestions();
}
test_inComment_endOfLine() {
addTestSource('''
main() {
// text ^
}
''');
expect(computeFast(), isTrue);
assertNoSuggestions();
}
test_is_expression() {
addTestSource('main() {if (x is^)}');
expect(computeFast(), isTrue);

View file

@ -603,6 +603,38 @@ class B extends A {
assertNotSuggested('MC');
}
test_inComment_block_beforeNode() {
addTestSource('''
main(aaa, bbb) {
/* text ^ */
print(42);
}
''');
expect(computeFast(), isTrue);
assertNoSuggestions();
}
test_inComment_endOfLine_beforeNode() {
addTestSource('''
main(aaa, bbb) {
// text ^
print(42);
}
''');
expect(computeFast(), isTrue);
assertNoSuggestions();
}
test_inComment_endOfLine_beforeToken() {
addTestSource('''
main(aaa, bbb) {
// text ^
}
''');
expect(computeFast(), isTrue);
assertNoSuggestions();
}
test_InstanceCreationExpression() {
addTestSource('''
class A {foo(){var f; {var x;}}}