Fix the parsing of literal symbols

Change-Id: I237871ee1c44d2819afbbee583ddd7e14b1ef043
Reviewed-on: https://dart-review.googlesource.com/54801
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Peter von der Ahé <ahe@google.com>
Reviewed-by: Dan Rubel <danrubel@google.com>
diff --git a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
index 9d763f0..06f0ab1 100644
--- a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
@@ -2,10 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart' hide Identifier;
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
+import 'package:front_end/src/fasta/kernel/body_builder.dart'
+    show Identifier, Operator;
 import 'package:front_end/src/fasta/kernel/forest.dart';
 import 'package:kernel/ast.dart' as kernel;
 
@@ -108,6 +110,9 @@
       astFactory.isExpression(expression, isOperator, notOperator, type);
 
   @override
+  bool isThisExpression(Object node) => node is ThisExpression;
+
+  @override
   Expression literalBool(bool value, Token location) =>
       astFactory.booleanLiteral(location, value)
         ..staticType = _typeProvider?.boolType;
@@ -157,9 +162,25 @@
         ..staticType = _typeProvider?.stringType;
 
   @override
-  Expression literalSymbol(String value, Token location) {
-    // TODO(brianwilkerson) Get the missing information.
-    return astFactory.symbolLiteral(location, null /* components */)
+  Expression literalSymbolMultiple(
+      String value, Token hash, List<Identifier> components) {
+    return astFactory.symbolLiteral(
+        hash, components.map((identifier) => identifier.token).toList())
+      ..staticType = _typeProvider?.symbolType;
+  }
+
+  @override
+  Expression literalSymbolSingluar(String value, Token hash, Object component) {
+    Token token;
+    if (component is Identifier) {
+      token = component.token;
+    } else if (component is Operator) {
+      token = component.token;
+    } else {
+      throw new ArgumentError(
+          'Unexpected class of component: ${component.runtimeType}');
+    }
+    return astFactory.symbolLiteral(hash, <Token>[token])
       ..staticType = _typeProvider?.symbolType;
   }
 
@@ -199,9 +220,6 @@
   @override
   Expression thisExpression(Token thisKeyword) =>
       astFactory.thisExpression(thisKeyword);
-
-  @override
-  bool isThisExpression(Object node) => node is ThisExpression;
 }
 
 /// A data holder used to conform to the [Forest] API.
diff --git a/pkg/analyzer/test/generated/parser_forest_test.dart b/pkg/analyzer/test/generated/parser_forest_test.dart
index ca0c110..fcb4f82 100644
--- a/pkg/analyzer/test/generated/parser_forest_test.dart
+++ b/pkg/analyzer/test/generated/parser_forest_test.dart
@@ -3373,31 +3373,6 @@
   }
 
   @failingTest
-  void test_parseSymbolLiteral_builtInIdentifier() {
-    super.test_parseSymbolLiteral_builtInIdentifier();
-  }
-
-  @failingTest
-  void test_parseSymbolLiteral_multiple() {
-    super.test_parseSymbolLiteral_multiple();
-  }
-
-  @failingTest
-  void test_parseSymbolLiteral_operator() {
-    super.test_parseSymbolLiteral_operator();
-  }
-
-  @failingTest
-  void test_parseSymbolLiteral_single() {
-    super.test_parseSymbolLiteral_single();
-  }
-
-  @failingTest
-  void test_parseSymbolLiteral_void() {
-    super.test_parseSymbolLiteral_void();
-  }
-
-  @failingTest
   void test_parseThrowExpression() {
     super.test_parseThrowExpression();
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 1c9efaf..51e72ca 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2002,15 +2002,17 @@
     debugEvent("LiteralSymbol");
     String value;
     if (identifierCount == 1) {
-      value = symbolPartToString(pop());
+      Object part = pop();
+      value = symbolPartToString(part);
+      push(forest.literalSymbolSingluar(value, hashToken, part));
     } else {
-      List parts = popList(identifierCount);
+      List<Identifier> parts = popList(identifierCount);
       value = symbolPartToString(parts.first);
       for (int i = 1; i < parts.length; i++) {
         value += ".${symbolPartToString(parts[i])}";
       }
+      push(forest.literalSymbolMultiple(value, hashToken, parts));
     }
-    push(forest.literalSymbol(value, hashToken));
   }
 
   @override
@@ -3913,7 +3915,7 @@
   @override
   void handleOperator(Token token) {
     debugEvent("Operator");
-    push(new Operator(token.stringValue, token.charOffset));
+    push(new Operator(token, token.charOffset));
   }
 
   @override
@@ -4142,11 +4144,12 @@
 }
 
 class Operator {
-  final String name;
+  final Token token;
+  String get name => token.stringValue;
 
   final int charOffset;
 
-  Operator(this.name, this.charOffset);
+  Operator(this.token, this.charOffset);
 
   String toString() => "operator($name)";
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index 3608a22..3f1e366 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -152,8 +152,13 @@
   }
 
   @override
-  ShadowSymbolLiteral literalSymbol(String value, Token token) {
-    return new ShadowSymbolLiteral(value)..fileOffset = offsetForToken(token);
+  ShadowSymbolLiteral literalSymbolMultiple(String value, Token hash, _) {
+    return new ShadowSymbolLiteral(value)..fileOffset = offsetForToken(hash);
+  }
+
+  @override
+  ShadowSymbolLiteral literalSymbolSingluar(String value, Token hash, _) {
+    return new ShadowSymbolLiteral(value)..fileOffset = offsetForToken(hash);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index 123d862..7ec6fac 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -4,6 +4,7 @@
 
 library fasta.forest;
 
+import 'body_builder.dart' show Identifier;
 // TODO(ahe): Remove this import.
 import 'package:kernel/ast.dart' as kernel show Arguments, DartType;
 
@@ -91,7 +92,16 @@
   /// either adjacent strings or interpolated strings.
   Expression literalString(String value, Location location);
 
-  Expression literalSymbol(String value, Location location);
+  /// Return a representation of a symbol literal defined by the [hash] and the
+  /// list of [components]. The [value] is the string value of the symbol.
+  Expression literalSymbolMultiple(
+      String value, Location hash, List<Identifier> components);
+
+  /// Return a representation of a symbol literal defined by the [hash] and the
+  /// single [component]. The component can be either an [Identifier] or an
+  /// [Operator]. The [value] is the string value of the symbol.
+  Expression literalSymbolSingluar(
+      String value, Location hash, Object component);
 
   Expression literalType(covariant type, Location location);