From 5cb949e5133f0d14fc3d805415b24557079feb6a Mon Sep 17 00:00:00 2001 From: Brian Wilkerson Date: Thu, 21 Jul 2016 09:13:02 -0700 Subject: [PATCH] Support references to operators in doc comments R=scheglov@google.com Review URL: https://codereview.chromium.org/2168833003 . --- pkg/analyzer/lib/src/generated/parser.dart | 48 +++++++++++++-- .../test/generated/element_resolver_test.dart | 19 ++++++ pkg/analyzer/test/generated/parser_test.dart | 60 +++++++++++++++++++ 3 files changed, 121 insertions(+), 6 deletions(-) diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart index 6e45c8e1441..f63bb70615a 100644 --- a/pkg/analyzer/lib/src/generated/parser.dart +++ b/pkg/analyzer/lib/src/generated/parser.dart @@ -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; diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart index da95f04e01e..7ddd33bc90e 100644 --- a/pkg/analyzer/test/generated/element_resolver_test.dart +++ b/pkg/analyzer/test/generated/element_resolver_test.dart @@ -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 = [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"; diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart index f6266355e92..e74309d6d31 100644 --- a/pkg/analyzer/test/generated/parser_test.dart +++ b/pkg/analyzer/test/generated/parser_test.dart @@ -6281,6 +6281,66 @@ void'''); expect(identifier.offset, 9); } + void test_parseCommentReference_operator_withKeyword_notPrefixed() { + CommentReference reference = + parse("parseCommentReference", ["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.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", ["==", 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.==", 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", ["a.b", 7], "");