| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file |  | 
| 2 // for details. All rights reserved. Use of this source code is governed by a |  | 
| 3 // BSD-style license that can be found in the LICENSE file. |  | 
| 4 |  | 
| 5 /// Algorithm to serialize expressions into the format used by summaries. |  | 
| 6 library summary.src.expression_serializer; |  | 
| 7 |  | 
| 8 import 'package:front_end/src/fasta/scanner/token_constants.dart'; |  | 
| 9 |  | 
| 10 import 'model.dart'; |  | 
| 11 |  | 
| 12 /// Translate a parser binary operation into an operation in the summary format. |  | 
| 13 UnlinkedExprOperation _binaryOpFor(int operatorKind) { |  | 
| 14   switch (operatorKind) { |  | 
| 15     case AMPERSAND_TOKEN: |  | 
| 16       return UnlinkedExprOperation.bitAnd; |  | 
| 17     case AMPERSAND_AMPERSAND_TOKEN: |  | 
| 18       return UnlinkedExprOperation.and; |  | 
| 19     case BANG_EQ_TOKEN: |  | 
| 20       return UnlinkedExprOperation.notEqual; |  | 
| 21     case BAR_TOKEN: |  | 
| 22       return UnlinkedExprOperation.bitOr; |  | 
| 23     case BAR_BAR_TOKEN: |  | 
| 24       return UnlinkedExprOperation.or; |  | 
| 25     case CARET_TOKEN: |  | 
| 26       return UnlinkedExprOperation.bitXor; |  | 
| 27     case EQ_EQ_TOKEN: |  | 
| 28       return UnlinkedExprOperation.equal; |  | 
| 29     case GT_TOKEN: |  | 
| 30       return UnlinkedExprOperation.greater; |  | 
| 31     case GT_EQ_TOKEN: |  | 
| 32       return UnlinkedExprOperation.greaterEqual; |  | 
| 33     case GT_GT_TOKEN: |  | 
| 34       return UnlinkedExprOperation.bitShiftRight; |  | 
| 35     case LT_TOKEN: |  | 
| 36       return UnlinkedExprOperation.less; |  | 
| 37     case LT_EQ_TOKEN: |  | 
| 38       return UnlinkedExprOperation.lessEqual; |  | 
| 39     case LT_LT_TOKEN: |  | 
| 40       return UnlinkedExprOperation.bitShiftLeft; |  | 
| 41     case MINUS_TOKEN: |  | 
| 42       return UnlinkedExprOperation.subtract; |  | 
| 43     case PERCENT_TOKEN: |  | 
| 44       return UnlinkedExprOperation.modulo; |  | 
| 45     case PERIOD_TOKEN: |  | 
| 46       return UnlinkedExprOperation.extractProperty; |  | 
| 47     case PLUS_TOKEN: |  | 
| 48       return UnlinkedExprOperation.add; |  | 
| 49     case QUESTION_QUESTION_TOKEN: |  | 
| 50       return UnlinkedExprOperation.ifNull; |  | 
| 51     case SLASH_TOKEN: |  | 
| 52       return UnlinkedExprOperation.divide; |  | 
| 53     case STAR_TOKEN: |  | 
| 54       return UnlinkedExprOperation.multiply; |  | 
| 55     case TILDE_SLASH_TOKEN: |  | 
| 56       return UnlinkedExprOperation.floorDivide; |  | 
| 57     default: |  | 
| 58       throw "Unhandled openratorKind $operatorKind"; |  | 
| 59   } |  | 
| 60 } |  | 
| 61 |  | 
| 62 /// Translate a parser unary operation into an operation in the summary format. |  | 
| 63 UnlinkedExprOperation _unaryOpFor(int operatorKind) { |  | 
| 64   switch (operatorKind) { |  | 
| 65     case BANG_TOKEN: |  | 
| 66       return UnlinkedExprOperation.not; |  | 
| 67     case MINUS_TOKEN: |  | 
| 68       return UnlinkedExprOperation.negate; |  | 
| 69     default: |  | 
| 70       throw "Unhandled operator kind $operatorKind"; |  | 
| 71   } |  | 
| 72 } |  | 
| 73 |  | 
| 74 /// Visitor over the minimal expression AST to convert them into stack-like |  | 
| 75 /// expressions used in the summary format. |  | 
| 76 class Serializer extends RecursiveVisitor { |  | 
| 77   UnlinkedExprBuilder expression; |  | 
| 78   final Scope scope; |  | 
| 79   final bool forConst; |  | 
| 80 |  | 
| 81   Serializer(this.scope, this.forConst); |  | 
| 82 |  | 
| 83   handleAs(As n) { |  | 
| 84     throw new UnimplementedError(); // TODO(paulberry): fix the code below. |  | 
| 85     // handleType(a.type); |  | 
| 86     // expression.operations.add(UnlinkedExprOperation.typeCast); |  | 
| 87   } |  | 
| 88 |  | 
| 89   handleBinary(Binary n) { |  | 
| 90     expression.operations.add(_binaryOpFor(n.operator)); |  | 
| 91   } |  | 
| 92 |  | 
| 93   handleBool(BoolLiteral n) { |  | 
| 94     expression.operations.add(n.value |  | 
| 95         ? UnlinkedExprOperation.pushTrue |  | 
| 96         : UnlinkedExprOperation.pushFalse); |  | 
| 97   } |  | 
| 98 |  | 
| 99   handleConditional(Conditional n) { |  | 
| 100     expression.operations.add(UnlinkedExprOperation.conditional); |  | 
| 101   } |  | 
| 102 |  | 
| 103   handleConstCreation(ConstCreation n) { |  | 
| 104     var ctor = n.constructor; |  | 
| 105     var type = handleType(ctor.type); |  | 
| 106     if (ctor.name != null) { |  | 
| 107       throw new UnimplementedError(); // TODO(paulberry): fix the code below. |  | 
| 108       //var classRef = handleRef(ctor.type.name, push: false); |  | 
| 109       //var top = scope.top; |  | 
| 110       //var ref = new LazyEntityRef(ctor.name, top) |  | 
| 111       //  ..reference = (scope.serializeReference(classRef.reference, ctor.name)
     ) |  | 
| 112       //  ..typeArguments = type.typeArguments |  | 
| 113       //  ..wasExpanded = true; |  | 
| 114       //expression.references.add(ref); |  | 
| 115     } else { |  | 
| 116       expression.references.add(type); |  | 
| 117     } |  | 
| 118     expression.ints.add(n.namedArgs.length); |  | 
| 119     expression.ints.add(n.positionalArgs.length); |  | 
| 120     expression.strings.addAll(n.namedArgs.map((a) => a.name)); |  | 
| 121     expression.operations.add(UnlinkedExprOperation.invokeConstructor); |  | 
| 122   } |  | 
| 123 |  | 
| 124   handleDouble(DoubleLiteral n) { |  | 
| 125     expression.operations.add(UnlinkedExprOperation.pushDouble); |  | 
| 126     expression.doubles.add(n.value); |  | 
| 127   } |  | 
| 128 |  | 
| 129   handleIdentical(Identical n) { |  | 
| 130     expression.references.add(handleRef(new Ref('identical'), push: false)); |  | 
| 131     expression.ints.add(0); |  | 
| 132     expression.ints.add(2); |  | 
| 133     expression.ints.add(0); |  | 
| 134     expression.operations.add(UnlinkedExprOperation.invokeMethodRef); |  | 
| 135   } |  | 
| 136 |  | 
| 137   handleInt(IntLiteral n) { |  | 
| 138     var ints = expression.ints; |  | 
| 139     var operations = expression.operations; |  | 
| 140     int value = n.value; |  | 
| 141     assert(value >= 0); |  | 
| 142     if (value >= (1 << 32)) { |  | 
| 143       int numOfComponents = 0; |  | 
| 144       expression.ints.add(numOfComponents); |  | 
| 145       void pushComponents(int value) { |  | 
| 146         if (value >= (1 << 32)) { |  | 
| 147           pushComponents(value >> 32); |  | 
| 148         } |  | 
| 149         numOfComponents++; |  | 
| 150         ints.add(value & 0xFFFFFFFF); |  | 
| 151       } |  | 
| 152 |  | 
| 153       pushComponents(value); |  | 
| 154       ints[ints.length - 1 - numOfComponents] = numOfComponents; |  | 
| 155       operations.add(UnlinkedExprOperation.pushLongInt); |  | 
| 156     } else { |  | 
| 157       operations.add(UnlinkedExprOperation.pushInt); |  | 
| 158       ints.add(value); |  | 
| 159     } |  | 
| 160   } |  | 
| 161 |  | 
| 162   handleInvalid(Invalid n) { |  | 
| 163     expression.isValidConst = false; |  | 
| 164     throw new UnimplementedError(); // TODO(paulberry): fix the code below. |  | 
| 165     // expression.operations.add(UnlinkedExprOperation.pushInvalidor); |  | 
| 166   } |  | 
| 167 |  | 
| 168   handleIs(Is n) { |  | 
| 169     throw new UnimplementedError(); // TODO(paulberry): fix the code below. |  | 
| 170     // handleType(i.type); |  | 
| 171     // expression.operations.add(UnlinkedExprOperation.typeCheck); |  | 
| 172   } |  | 
| 173 |  | 
| 174   handleList(ListLiteral n) { |  | 
| 175     expression.ints.add(n.values.length); |  | 
| 176     if (n.elementType == null) { |  | 
| 177       expression.operations.add(UnlinkedExprOperation.makeUntypedList); |  | 
| 178     } else { |  | 
| 179       handleType(n.elementType); |  | 
| 180       expression.operations.add(UnlinkedExprOperation.makeTypedList); |  | 
| 181     } |  | 
| 182   } |  | 
| 183 |  | 
| 184   handleLoad(Load n) { |  | 
| 185     expression.strings.add(n.name); |  | 
| 186     expression.operations.add(UnlinkedExprOperation.extractProperty); |  | 
| 187   } |  | 
| 188 |  | 
| 189   handleMap(MapLiteral n) { |  | 
| 190     expression.ints.add(n.values.length); |  | 
| 191     if (n.types.isEmpty) { |  | 
| 192       expression.operations.add(UnlinkedExprOperation.makeUntypedMap); |  | 
| 193     } else { |  | 
| 194       n.types.forEach(handleType); |  | 
| 195       expression.operations.add(UnlinkedExprOperation.makeTypedMap); |  | 
| 196     } |  | 
| 197   } |  | 
| 198 |  | 
| 199   handleNull(NullLiteral n) { |  | 
| 200     expression.operations.add(UnlinkedExprOperation.pushNull); |  | 
| 201   } |  | 
| 202 |  | 
| 203   handleOpaque(Opaque n) { |  | 
| 204     if (n.type != null) { |  | 
| 205       handleType(n.type); |  | 
| 206       expression.operations.add(UnlinkedExprOperation.pushTypedAbstract); |  | 
| 207     } else { |  | 
| 208       expression.operations.add(UnlinkedExprOperation.pushUntypedAbstract); |  | 
| 209     } |  | 
| 210   } |  | 
| 211 |  | 
| 212   handleOpaqueOp(OpaqueOp n) { |  | 
| 213     // nothing to do, recursive visitor serialized subexpression. |  | 
| 214   } |  | 
| 215 |  | 
| 216   handleRef(Ref n, {push: true}) { |  | 
| 217     var ref = n.prefix == null |  | 
| 218         ? new LazyEntityRef(n.name, scope) |  | 
| 219         : new NestedLazyEntityRef( |  | 
| 220             handleRef(n.prefix, push: false), n.name, scope); |  | 
| 221     if (push) { |  | 
| 222       expression.references.add(ref); |  | 
| 223       expression.operations.add(UnlinkedExprOperation.pushReference); |  | 
| 224     } |  | 
| 225     return ref; |  | 
| 226   } |  | 
| 227 |  | 
| 228   handleString(StringLiteral n) { |  | 
| 229     expression.strings.add(n.value); |  | 
| 230     expression.operations.add(UnlinkedExprOperation.pushString); |  | 
| 231   } |  | 
| 232 |  | 
| 233   handleSymbol(SymbolLiteral n) { |  | 
| 234     expression.strings.add(n.value); |  | 
| 235     expression.operations.add(UnlinkedExprOperation.makeSymbol); |  | 
| 236   } |  | 
| 237 |  | 
| 238   handleType(TypeRef n) { |  | 
| 239     var t = handleRef(n.name, push: false); |  | 
| 240     var args = n.typeArguments ?? []; |  | 
| 241     t.typeArguments = args.map((a) => handleType(a)).toList(); |  | 
| 242     return t; |  | 
| 243   } |  | 
| 244 |  | 
| 245   handleUnary(Unary n) { |  | 
| 246     expression.operations.add(_unaryOpFor(n.operator)); |  | 
| 247   } |  | 
| 248 |  | 
| 249   run(Expression root) { |  | 
| 250     expression = new UnlinkedExprBuilder( |  | 
| 251         isValidConst: forConst, |  | 
| 252         operations: [], |  | 
| 253         assignmentOperators: [], |  | 
| 254         ints: [], |  | 
| 255         doubles: [], |  | 
| 256         strings: [], |  | 
| 257         references: []); |  | 
| 258     root.accept(this); |  | 
| 259     expression.references.forEach((r) => (r as LazyEntityRef).expand()); |  | 
| 260     return expression; |  | 
| 261   } |  | 
| 262 } |  | 
| OLD | NEW | 
|---|