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

Unified Diff: pkg/analyzer/lib/src/summary/fasta/expression_serializer.dart

Issue 2738273002: Add fasta-based summary generation code. (Closed)
Patch Set: Actually disable the test Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer/lib/src/summary/fasta/expression_serializer.dart
diff --git a/pkg/analyzer/lib/src/summary/fasta/expression_serializer.dart b/pkg/analyzer/lib/src/summary/fasta/expression_serializer.dart
new file mode 100644
index 0000000000000000000000000000000000000000..3d60dd483afe434bccf203ca6fe1775afd8161d6
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/fasta/expression_serializer.dart
@@ -0,0 +1,237 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// 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.
+
+/// Algorithm to serialize expressions into the format used by summaries.
+library summary.src.expression_serializer;
+
+import 'model.dart';
+import 'package:front_end/src/fasta/scanner/token_constants.dart';
+
+/// Visitor over the minimal expression AST to convert them into stack-like
+/// expressions used in the summary format.
+class Serializer extends RecursiveVisitor {
+ UnlinkedExprBuilder expression;
+ final Scope scope;
+ final bool forConst;
+
+ Serializer(this.scope, this.forConst);
+
+ run(Expression root) {
+ expression = new UnlinkedExprBuilder(
+ isValidConst: forConst,
+ operations: [],
+ assignmentOperators: [],
+ ints: [],
+ doubles: [],
+ strings: [],
+ references: []);
+ root.accept(this);
+ expression.references.forEach((r) => (r as LazyEntityRef).expand());
+ return expression;
+ }
+
+ handleRef(Ref n, {push: true}) {
+ var ref = n.prefix == null
+ ? new LazyEntityRef(n.name, scope)
+ : new NestedLazyEntityRef(
+ handleRef(n.prefix, push: false), n.name, scope);
+ if (push) {
+ expression.references.add(ref);
+ expression.operations.add(UnlinkedExprOperation.pushReference);
+ }
+ return ref;
+ }
+
+ handleNull(NullLiteral n) {
+ expression.operations.add(UnlinkedExprOperation.pushNull);
+ }
+
+ handleBool(BoolLiteral n) {
+ expression.operations.add(n.value
+ ? UnlinkedExprOperation.pushTrue
+ : UnlinkedExprOperation.pushFalse);
+ }
+
+ handleInt(IntLiteral n) {
+ var ints = expression.ints;
+ var operations = expression.operations;
+ int value = n.value;
+ assert(value >= 0);
+ if (value >= (1 << 32)) {
+ int numOfComponents = 0;
+ expression.ints.add(numOfComponents);
+ void pushComponents(int value) {
+ if (value >= (1 << 32)) {
+ pushComponents(value >> 32);
+ }
+ numOfComponents++;
+ ints.add(value & 0xFFFFFFFF);
+ }
+ pushComponents(value);
+ ints[ints.length - 1 - numOfComponents] = numOfComponents;
+ operations.add(UnlinkedExprOperation.pushLongInt);
+ } else {
+ operations.add(UnlinkedExprOperation.pushInt);
+ ints.add(value);
+ }
+ }
+
+ handleDouble(DoubleLiteral n) {
+ expression.operations.add(UnlinkedExprOperation.pushDouble);
+ expression.doubles.add(n.value);
+ }
+
+ handleType(TypeRef n) {
+ var t = handleRef(n.name, push: false);
+ var args = n.typeArguments ?? [];
+ t.typeArguments = args.map((a) => handleType(a)).toList();
+ return t;
+ }
+
+ handleList(ListLiteral n) {
+ expression.ints.add(n.values.length);
+ if (n.elementType == null) {
+ expression.operations.add(UnlinkedExprOperation.makeUntypedList);
+ } else {
+ handleType(n.elementType);
+ expression.operations.add(UnlinkedExprOperation.makeTypedList);
+ }
+ }
+
+ handleMap(MapLiteral n) {
+ expression.ints.add(n.values.length);
+ if (n.types.isEmpty) {
+ expression.operations.add(UnlinkedExprOperation.makeUntypedMap);
+ } else {
+ n.types.forEach(handleType);
+ expression.operations.add(UnlinkedExprOperation.makeTypedMap);
+ }
+ }
+
+ handleString(StringLiteral n) {
+ expression.strings.add(n.value);
+ expression.operations.add(UnlinkedExprOperation.pushString);
+ }
+
+ handleSymbol(SymbolLiteral n) {
+ expression.strings.add(n.value);
+ expression.operations.add(UnlinkedExprOperation.makeSymbol);
+ }
+
+ handleAs(As n) {
+ throw new UnimplementedError(); // TODO(paulberry): fix the code below.
+ // handleType(a.type);
+ // expression.operations.add(UnlinkedExprOperation.typeCast);
+ }
+
+ handleIs(Is n) {
+ throw new UnimplementedError(); // TODO(paulberry): fix the code below.
+ // handleType(i.type);
+ // expression.operations.add(UnlinkedExprOperation.typeCheck);
+ }
+
+ handleUnary(Unary n) {
+ expression.operations.add(_unaryOpFor(n.operator));
+ }
+
+ handleBinary(Binary n){
+ expression.operations.add(_binaryOpFor(n.operator));
+ }
+
+ handleLoad(Load n){
+ expression.strings.add(n.name);
+ expression.operations.add(UnlinkedExprOperation.extractProperty);
+ }
+
+ handleIdentical(Identical n){
+ expression.references.add(handleRef(new Ref('identical'), push: false));
+ expression.ints.add(0);
+ expression.ints.add(2);
+ expression.ints.add(0);
+ expression.operations.add(UnlinkedExprOperation.invokeMethodRef);
+ }
+
+ handleConditional(Conditional n) {
+ expression.operations.add(UnlinkedExprOperation.conditional);
+ }
+
+ handleConstCreation(ConstCreation n) {
+ var ctor = n.constructor;
+ var type = handleType(ctor.type);
+ if (ctor.name != null) {
+ throw new UnimplementedError(); // TODO(paulberry): fix the code below.
+ //var classRef = handleRef(ctor.type.name, push: false);
+ //var top = scope.top;
+ //var ref = new LazyEntityRef(ctor.name, top)
+ // ..reference = (scope.serializeReference(classRef.reference, ctor.name))
+ // ..typeArguments = type.typeArguments
+ // ..wasExpanded = true;
+ //expression.references.add(ref);
+ } else {
+ expression.references.add(type);
+ }
+ expression.ints.add(n.namedArgs.length);
+ expression.ints.add(n.positionalArgs.length);
+ expression.strings.addAll(n.namedArgs.map((a) => a.name));
+ expression.operations.add(UnlinkedExprOperation.invokeConstructor);
+ }
+
+ handleInvalid(Invalid n) {
+ expression.isValidConst = false;
+ throw new UnimplementedError(); // TODO(paulberry): fix the code below.
+ // expression.operations.add(UnlinkedExprOperation.pushInvalidor);
+ }
+
+ handleOpaque(Opaque n) {
+ if (n.type != null) {
+ handleType(n.type);
+ expression.operations.add(UnlinkedExprOperation.pushTypedAbstract);
+ } else {
+ expression.operations.add(UnlinkedExprOperation.pushUntypedAbstract);
+ }
+ }
+
+ handleOpaqueOp(OpaqueOp n) {
+ // nothing to do, recursive visitor serialized subexpression.
+ }
+}
+
+/// Translate a parser unary operation into an operation in the summary format.
+UnlinkedExprOperation _unaryOpFor(int operatorKind) {
+ switch (operatorKind) {
+ case BANG_TOKEN: return UnlinkedExprOperation.not;
+ case MINUS_TOKEN: return UnlinkedExprOperation.negate;
+ default:
+ throw "Unhandled operator kind $operatorKind";
+ }
+}
+
+/// Translate a parser binary operation into an operation in the summary format.
+UnlinkedExprOperation _binaryOpFor(int operatorKind) {
+ switch (operatorKind) {
+ case AMPERSAND_TOKEN: return UnlinkedExprOperation.bitAnd;
+ case AMPERSAND_AMPERSAND_TOKEN: return UnlinkedExprOperation.and;
+ case BANG_EQ_TOKEN: return UnlinkedExprOperation.notEqual;
+ case BAR_TOKEN: return UnlinkedExprOperation.bitOr;
+ case BAR_BAR_TOKEN: return UnlinkedExprOperation.or;
+ case CARET_TOKEN: return UnlinkedExprOperation.bitXor;
+ case EQ_EQ_TOKEN: return UnlinkedExprOperation.equal;
+ case GT_TOKEN: return UnlinkedExprOperation.greater;
+ case GT_EQ_TOKEN: return UnlinkedExprOperation.greaterEqual;
+ case GT_GT_TOKEN: return UnlinkedExprOperation.bitShiftRight;
+ case LT_TOKEN: return UnlinkedExprOperation.less;
+ case LT_EQ_TOKEN: return UnlinkedExprOperation.lessEqual;
+ case LT_LT_TOKEN: return UnlinkedExprOperation.bitShiftLeft;
+ case MINUS_TOKEN: return UnlinkedExprOperation.subtract;
+ case PERCENT_TOKEN: return UnlinkedExprOperation.modulo;
+ case PERIOD_TOKEN: return UnlinkedExprOperation.extractProperty;
+ case PLUS_TOKEN: return UnlinkedExprOperation.add;
+ case QUESTION_QUESTION_TOKEN: return UnlinkedExprOperation.ifNull;
+ case SLASH_TOKEN: return UnlinkedExprOperation.divide;
+ case STAR_TOKEN: return UnlinkedExprOperation.multiply;
+ case TILDE_SLASH_TOKEN: return UnlinkedExprOperation.floorDivide;
+ default:
+ throw "Unhandled openratorKind $operatorKind";
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698