| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart2js.constants.expressions; | 5 library dart2js.constants.expressions; |
| 6 | 6 |
| 7 import '../dart2jslib.dart' show assertDebugMode; | 7 import '../dart2jslib.dart' show assertDebugMode; |
| 8 import '../dart_types.dart'; | 8 import '../dart_types.dart'; |
| 9 import '../elements/elements.dart' show | 9 import '../elements/elements.dart' show |
| 10 Element, | 10 Element, |
| 11 FunctionElement, | 11 FunctionElement, |
| 12 VariableElement; | 12 VariableElement; |
| 13 import '../resolution/operators.dart'; |
| 13 import '../universe/universe.dart' show CallStructure; | 14 import '../universe/universe.dart' show CallStructure; |
| 14 import 'values.dart'; | 15 import 'values.dart'; |
| 15 | 16 |
| 16 /// An expression that is a compile-time constant. | 17 /// An expression that is a compile-time constant. |
| 17 /// | 18 /// |
| 18 /// Whereas [ConstantValue] represent a compile-time value, a | 19 /// Whereas [ConstantValue] represent a compile-time value, a |
| 19 /// [ConstantExpression] represents an expression for creating a constant. | 20 /// [ConstantExpression] represents an expression for creating a constant. |
| 20 /// | 21 /// |
| 21 /// There is no one-to-one mapping between [ConstantExpression] and | 22 /// There is no one-to-one mapping between [ConstantExpression] and |
| 22 /// [ConstantValue], because different expressions can denote the same constant. | 23 /// [ConstantValue], because different expressions can denote the same constant. |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 final FunctionConstantValue value; | 176 final FunctionConstantValue value; |
| 176 final FunctionElement element; | 177 final FunctionElement element; |
| 177 | 178 |
| 178 FunctionConstantExpression(this.value, this.element); | 179 FunctionConstantExpression(this.value, this.element); |
| 179 | 180 |
| 180 accept(ConstantExpressionVisitor visitor, [context]) { | 181 accept(ConstantExpressionVisitor visitor, [context]) { |
| 181 return visitor.visitFunction(this, context); | 182 return visitor.visitFunction(this, context); |
| 182 } | 183 } |
| 183 } | 184 } |
| 184 | 185 |
| 185 /// A constant binary expression like `a * b` or `identical(a, b)`. | 186 /// A constant binary expression like `a * b`. |
| 186 class BinaryConstantExpression extends ConstantExpression { | 187 class BinaryConstantExpression extends ConstantExpression { |
| 187 final ConstantValue value; | 188 final ConstantValue value; |
| 188 final ConstantExpression left; | 189 final ConstantExpression left; |
| 189 final String operator; | 190 final BinaryOperator operator; |
| 190 final ConstantExpression right; | 191 final ConstantExpression right; |
| 191 | 192 |
| 192 BinaryConstantExpression(this.value, this.left, this.operator, this.right) { | 193 BinaryConstantExpression(this.value, this.left, this.operator, this.right) { |
| 193 assert(PRECEDENCE_MAP[operator] != null); | 194 assert(PRECEDENCE_MAP[operator.kind] != null); |
| 194 } | 195 } |
| 195 | 196 |
| 196 accept(ConstantExpressionVisitor visitor, [context]) { | 197 accept(ConstantExpressionVisitor visitor, [context]) { |
| 197 return visitor.visitBinary(this, context); | 198 return visitor.visitBinary(this, context); |
| 198 } | 199 } |
| 199 | 200 |
| 200 int get precedence => PRECEDENCE_MAP[operator]; | 201 int get precedence => PRECEDENCE_MAP[operator.kind]; |
| 201 | 202 |
| 202 static const Map<String, int> PRECEDENCE_MAP = const { | 203 static const Map<BinaryOperatorKind, int> PRECEDENCE_MAP = const { |
| 203 'identical': 15, | 204 BinaryOperatorKind.EQ: 6, |
| 204 '==': 6, | 205 BinaryOperatorKind.NOT_EQ: 6, |
| 205 '!=': 6, | 206 BinaryOperatorKind.LOGICAL_AND: 5, |
| 206 '&&': 5, | 207 BinaryOperatorKind.LOGICAL_OR: 4, |
| 207 '||': 4, | 208 BinaryOperatorKind.XOR: 9, |
| 208 '^': 9, | 209 BinaryOperatorKind.AND: 10, |
| 209 '&': 10, | 210 BinaryOperatorKind.OR: 8, |
| 210 '|': 8, | 211 BinaryOperatorKind.SHR: 11, |
| 211 '>>': 11, | 212 BinaryOperatorKind.SHL: 11, |
| 212 '<<': 11, | 213 BinaryOperatorKind.ADD: 12, |
| 213 '+': 12, | 214 BinaryOperatorKind.SUB: 12, |
| 214 '-': 12, | 215 BinaryOperatorKind.MUL: 13, |
| 215 '*': 13, | 216 BinaryOperatorKind.DIV: 13, |
| 216 '/': 13, | 217 BinaryOperatorKind.IDIV: 13, |
| 217 '~/': 13, | 218 BinaryOperatorKind.GT: 7, |
| 218 '>': 7, | 219 BinaryOperatorKind.LT: 7, |
| 219 '<': 7, | 220 BinaryOperatorKind.GTEQ: 7, |
| 220 '>=': 7, | 221 BinaryOperatorKind.LTEQ: 7, |
| 221 '<=': 7, | 222 BinaryOperatorKind.MOD: 13, |
| 222 '%': 13, | |
| 223 }; | 223 }; |
| 224 } | 224 } |
| 225 | 225 |
| 226 /// A constant identical invocation like `identical(a, b)`. |
| 227 class IdenticalConstantExpression extends ConstantExpression { |
| 228 final ConstantValue value; |
| 229 final ConstantExpression left; |
| 230 final ConstantExpression right; |
| 231 |
| 232 IdenticalConstantExpression(this.value, this.left, this.right); |
| 233 |
| 234 accept(ConstantExpressionVisitor visitor, [context]) { |
| 235 return visitor.visitIdentical(this, context); |
| 236 } |
| 237 |
| 238 int get precedence => 15; |
| 239 } |
| 240 |
| 226 /// A unary constant expression like `-a`. | 241 /// A unary constant expression like `-a`. |
| 227 class UnaryConstantExpression extends ConstantExpression { | 242 class UnaryConstantExpression extends ConstantExpression { |
| 228 final ConstantValue value; | 243 final ConstantValue value; |
| 229 final String operator; | 244 final UnaryOperator operator; |
| 230 final ConstantExpression expression; | 245 final ConstantExpression expression; |
| 231 | 246 |
| 232 UnaryConstantExpression(this.value, this.operator, this.expression) { | 247 UnaryConstantExpression(this.value, this.operator, this.expression) { |
| 233 assert(PRECEDENCE_MAP[operator] != null); | 248 assert(PRECEDENCE_MAP[operator.kind] != null); |
| 234 } | 249 } |
| 235 | 250 |
| 236 accept(ConstantExpressionVisitor visitor, [context]) { | 251 accept(ConstantExpressionVisitor visitor, [context]) { |
| 237 return visitor.visitUnary(this, context); | 252 return visitor.visitUnary(this, context); |
| 238 } | 253 } |
| 239 | 254 |
| 240 int get precedence => PRECEDENCE_MAP[operator]; | 255 int get precedence => PRECEDENCE_MAP[operator.kind]; |
| 241 | 256 |
| 242 static const Map<String, int> PRECEDENCE_MAP = const { | 257 static const Map<UnaryOperatorKind, int> PRECEDENCE_MAP = const { |
| 243 '!': 14, | 258 UnaryOperatorKind.NOT: 14, |
| 244 '~': 14, | 259 UnaryOperatorKind.COMPLEMENT: 14, |
| 245 '-': 14, | 260 UnaryOperatorKind.NEGATE: 14, |
| 246 }; | 261 }; |
| 247 } | 262 } |
| 248 | 263 |
| 249 /// A constant conditional expression like `a ? b : c`. | 264 /// A constant conditional expression like `a ? b : c`. |
| 250 class ConditionalConstantExpression extends ConstantExpression { | 265 class ConditionalConstantExpression extends ConstantExpression { |
| 251 final ConstantValue value; | 266 final ConstantValue value; |
| 252 final ConstantExpression condition; | 267 final ConstantExpression condition; |
| 253 final ConstantExpression trueExp; | 268 final ConstantExpression trueExp; |
| 254 final ConstantExpression falseExp; | 269 final ConstantExpression falseExp; |
| 255 | 270 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 275 R visitPrimitive(PrimitiveConstantExpression exp, C context); | 290 R visitPrimitive(PrimitiveConstantExpression exp, C context); |
| 276 R visitList(ListConstantExpression exp, C context); | 291 R visitList(ListConstantExpression exp, C context); |
| 277 R visitMap(MapConstantExpression exp, C context); | 292 R visitMap(MapConstantExpression exp, C context); |
| 278 R visitConstructed(ConstructedConstantExpression exp, C context); | 293 R visitConstructed(ConstructedConstantExpression exp, C context); |
| 279 R visitConcatenate(ConcatenateConstantExpression exp, C context); | 294 R visitConcatenate(ConcatenateConstantExpression exp, C context); |
| 280 R visitSymbol(SymbolConstantExpression exp, C context); | 295 R visitSymbol(SymbolConstantExpression exp, C context); |
| 281 R visitType(TypeConstantExpression exp, C context); | 296 R visitType(TypeConstantExpression exp, C context); |
| 282 R visitVariable(VariableConstantExpression exp, C context); | 297 R visitVariable(VariableConstantExpression exp, C context); |
| 283 R visitFunction(FunctionConstantExpression exp, C context); | 298 R visitFunction(FunctionConstantExpression exp, C context); |
| 284 R visitBinary(BinaryConstantExpression exp, C context); | 299 R visitBinary(BinaryConstantExpression exp, C context); |
| 300 R visitIdentical(IdenticalConstantExpression exp, C context); |
| 285 R visitUnary(UnaryConstantExpression exp, C context); | 301 R visitUnary(UnaryConstantExpression exp, C context); |
| 286 R visitConditional(ConditionalConstantExpression exp, C context); | 302 R visitConditional(ConditionalConstantExpression exp, C context); |
| 287 } | 303 } |
| 288 | 304 |
| 289 /// Represents the declaration of a constant [element] with value [expression]. | 305 /// Represents the declaration of a constant [element] with value [expression]. |
| 290 // TODO(johnniwinther): Where does this class belong? | 306 // TODO(johnniwinther): Where does this class belong? |
| 291 class ConstDeclaration { | 307 class ConstDeclaration { |
| 292 final VariableElement element; | 308 final VariableElement element; |
| 293 final ConstantExpression expression; | 309 final ConstantExpression expression; |
| 294 | 310 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 void visitFunction(FunctionConstantExpression exp, [_]) { | 444 void visitFunction(FunctionConstantExpression exp, [_]) { |
| 429 if (exp.element.isStatic) { | 445 if (exp.element.isStatic) { |
| 430 sb.write(exp.element.enclosingClass.name); | 446 sb.write(exp.element.enclosingClass.name); |
| 431 sb.write('.'); | 447 sb.write('.'); |
| 432 } | 448 } |
| 433 sb.write(exp.element.name); | 449 sb.write(exp.element.name); |
| 434 } | 450 } |
| 435 | 451 |
| 436 @override | 452 @override |
| 437 void visitBinary(BinaryConstantExpression exp, [_]) { | 453 void visitBinary(BinaryConstantExpression exp, [_]) { |
| 438 if (exp.operator == 'identical') { | 454 write(exp, exp.left); |
| 439 sb.write('identical('); | 455 sb.write(' '); |
| 440 visit(exp.left); | 456 sb.write(exp.operator.name); |
| 441 sb.write(', '); | 457 sb.write(' '); |
| 442 visit(exp.right); | 458 write(exp, exp.right); |
| 443 sb.write(')'); | |
| 444 } else { | |
| 445 write(exp, exp.left); | |
| 446 sb.write(' '); | |
| 447 sb.write(exp.operator); | |
| 448 sb.write(' '); | |
| 449 write(exp, exp.right); | |
| 450 } | |
| 451 } | 459 } |
| 452 | 460 |
| 453 @override | 461 @override |
| 462 void visitIdentical(IdenticalConstantExpression exp, [_]) { |
| 463 sb.write('identical('); |
| 464 visit(exp.left); |
| 465 sb.write(', '); |
| 466 visit(exp.right); |
| 467 sb.write(')'); |
| 468 } |
| 469 |
| 470 @override |
| 454 void visitUnary(UnaryConstantExpression exp, [_]) { | 471 void visitUnary(UnaryConstantExpression exp, [_]) { |
| 455 sb.write(exp.operator); | 472 sb.write(exp.operator); |
| 456 write(exp, exp.expression); | 473 write(exp, exp.expression); |
| 457 } | 474 } |
| 458 | 475 |
| 459 @override | 476 @override |
| 460 void visitConditional(ConditionalConstantExpression exp, [_]) { | 477 void visitConditional(ConditionalConstantExpression exp, [_]) { |
| 461 write(exp, exp.condition, leftAssociative: false); | 478 write(exp, exp.condition, leftAssociative: false); |
| 462 sb.write(' ? '); | 479 sb.write(' ? '); |
| 463 write(exp, exp.trueExp); | 480 write(exp, exp.trueExp); |
| 464 sb.write(' : '); | 481 sb.write(' : '); |
| 465 write(exp, exp.falseExp); | 482 write(exp, exp.falseExp); |
| 466 } | 483 } |
| 467 | 484 |
| 468 String toString() => sb.toString(); | 485 String toString() => sb.toString(); |
| 469 } | 486 } |
| OLD | NEW |