Support references to operators in doc comments

R=scheglov@google.com

Review URL: https://codereview.chromium.org/2168833003 .
This commit is contained in:
Brian Wilkerson 2016-07-21 09:13:02 -07:00
parent 7cc544696f
commit 5cb949e513
3 changed files with 121 additions and 6 deletions

View file

@ -5049,16 +5049,52 @@ class Parser {
newKeyword = firstToken;
firstToken = firstToken.next;
}
if (_tokenMatchesIdentifier(firstToken)) {
if (firstToken.isUserDefinableOperator) {
if (firstToken.next.type != TokenType.EOF) {
return null;
}
Identifier identifier = new SimpleIdentifier(firstToken);
return new CommentReference(null, identifier);
} else if (_tokenMatchesKeyword(firstToken, Keyword.OPERATOR)) {
Token secondToken = firstToken.next;
if (secondToken.isUserDefinableOperator) {
if (secondToken.next.type != TokenType.EOF) {
return null;
}
Identifier identifier = new SimpleIdentifier(secondToken);
return new CommentReference(null, identifier);
}
return null;
} else if (_tokenMatchesIdentifier(firstToken)) {
Token secondToken = firstToken.next;
Token thirdToken = secondToken.next;
Token nextToken;
Identifier identifier;
if (_tokenMatches(secondToken, TokenType.PERIOD) &&
_tokenMatchesIdentifier(thirdToken)) {
identifier = new PrefixedIdentifier(new SimpleIdentifier(firstToken),
secondToken, new SimpleIdentifier(thirdToken));
nextToken = thirdToken.next;
if (_tokenMatches(secondToken, TokenType.PERIOD)) {
if (thirdToken.isUserDefinableOperator) {
identifier = new PrefixedIdentifier(
new SimpleIdentifier(firstToken),
secondToken,
new SimpleIdentifier(thirdToken));
nextToken = thirdToken.next;
} else if (_tokenMatchesKeyword(thirdToken, Keyword.OPERATOR)) {
Token fourthToken = thirdToken.next;
if (fourthToken.isUserDefinableOperator) {
identifier = new PrefixedIdentifier(
new SimpleIdentifier(firstToken),
secondToken,
new SimpleIdentifier(fourthToken));
nextToken = fourthToken.next;
} else {
return null;
}
} else if (_tokenMatchesIdentifier(thirdToken)) {
identifier = new PrefixedIdentifier(
new SimpleIdentifier(firstToken),
secondToken,
new SimpleIdentifier(thirdToken));
nextToken = thirdToken.next;
}
} else {
identifier = new SimpleIdentifier(firstToken);
nextToken = firstToken.next;

View file

@ -301,6 +301,25 @@ class ElementResolverTest extends EngineTestCase {
_listener.assertNoErrors();
}
void test_visitCommentReference_prefixedIdentifier_class_operator() {
ClassElementImpl classA = ElementFactory.classElement2("A");
// set method
MethodElement method =
ElementFactory.methodElement("==", _typeProvider.boolType);
classA.methods = <MethodElement>[method];
// set name scope
_visitor.nameScope = new EnclosedScope(null)
..defineNameWithoutChecking('A', classA);
// prepare "A.=="
PrefixedIdentifier prefixed = AstFactory.identifier5('A', '==');
CommentReference commentReference = new CommentReference(null, prefixed);
// resolve
_resolveNode(commentReference);
expect(prefixed.prefix.staticElement, classA);
expect(prefixed.identifier.staticElement, method);
_listener.assertNoErrors();
}
void test_visitConstructorName_named() {
ClassElementImpl classA = ElementFactory.classElement2("A");
String constructorName = "a";

View file

@ -6281,6 +6281,66 @@ void''');
expect(identifier.offset, 9);
}
void test_parseCommentReference_operator_withKeyword_notPrefixed() {
CommentReference reference =
parse("parseCommentReference", <Object>["operator ==", 5], "");
SimpleIdentifier identifier = EngineTestCase.assertInstanceOf(
(obj) => obj is SimpleIdentifier,
SimpleIdentifier,
reference.identifier);
expect(identifier.token, isNotNull);
expect(identifier.name, "==");
expect(identifier.offset, 14);
}
void test_parseCommentReference_operator_withKeyword_prefixed() {
CommentReference reference =
parse("parseCommentReference", <Object>["Object.operator==", 7], "");
PrefixedIdentifier prefixedIdentifier = EngineTestCase.assertInstanceOf(
(obj) => obj is PrefixedIdentifier,
PrefixedIdentifier,
reference.identifier);
SimpleIdentifier prefix = prefixedIdentifier.prefix;
expect(prefix.token, isNotNull);
expect(prefix.name, "Object");
expect(prefix.offset, 7);
expect(prefixedIdentifier.period, isNotNull);
SimpleIdentifier identifier = prefixedIdentifier.identifier;
expect(identifier.token, isNotNull);
expect(identifier.name, "==");
expect(identifier.offset, 22);
}
void test_parseCommentReference_operator_withoutKeyword_notPrefixed() {
CommentReference reference =
parse("parseCommentReference", <Object>["==", 5], "");
SimpleIdentifier identifier = EngineTestCase.assertInstanceOf(
(obj) => obj is SimpleIdentifier,
SimpleIdentifier,
reference.identifier);
expect(identifier.token, isNotNull);
expect(identifier.name, "==");
expect(identifier.offset, 5);
}
void test_parseCommentReference_operator_withoutKeyword_prefixed() {
CommentReference reference =
parse("parseCommentReference", <Object>["Object.==", 7], "");
PrefixedIdentifier prefixedIdentifier = EngineTestCase.assertInstanceOf(
(obj) => obj is PrefixedIdentifier,
PrefixedIdentifier,
reference.identifier);
SimpleIdentifier prefix = prefixedIdentifier.prefix;
expect(prefix.token, isNotNull);
expect(prefix.name, "Object");
expect(prefix.offset, 7);
expect(prefixedIdentifier.period, isNotNull);
SimpleIdentifier identifier = prefixedIdentifier.identifier;
expect(identifier.token, isNotNull);
expect(identifier.name, "==");
expect(identifier.offset, 14);
}
void test_parseCommentReference_prefixed() {
CommentReference reference =
parse("parseCommentReference", <Object>["a.b", 7], "");