mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:27:17 +00:00
c7524cc296
Bug: 37337 Change-Id: Ibda0d9233d480cc64732e9e17182b55cde77baf2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107181 Reviewed-by: Mayank Patke <fishythefish@google.com> Commit-Queue: Stephen Adams <sra@google.com>
180 lines
6.6 KiB
Dart
180 lines
6.6 KiB
Dart
// Copyright (c) 2019, 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.
|
|
|
|
import 'package:expect/expect.dart';
|
|
import 'package:js_ast/js_ast.dart';
|
|
|
|
main() {
|
|
Map<Expression, DeferredExpression> map = {};
|
|
VariableUse variableUse = new VariableUse('variable');
|
|
DeferredExpression deferred =
|
|
map[variableUse] = new _DeferredExpression(variableUse);
|
|
VariableUse variableUseAlias = new VariableUse('variable');
|
|
map[variableUseAlias] = new _DeferredExpression(variableUseAlias);
|
|
|
|
map[deferred] = new _DeferredExpression(deferred);
|
|
Literal literal = new LiteralString('"literal"');
|
|
map[literal] = new _DeferredExpression(literal);
|
|
|
|
test(map, '#', [variableUse], 'variable');
|
|
test(map, '#', [deferred], 'variable');
|
|
test(map, '{#: #}', [literal, variableUse], '{literal: variable}');
|
|
test(map, '{#: #}', [literal, deferred], '{literal: variable}');
|
|
test(map, '#.#', [variableUse, literal], 'variable.literal');
|
|
test(map, '#.#', [deferred, literal], 'variable.literal');
|
|
test(map, '# = # + 1', [variableUse, variableUseAlias], '++variable');
|
|
test(map, '# = # + 1', [deferred, variableUseAlias], '++variable');
|
|
test(map, '# = # - 1', [variableUse, variableUseAlias], '--variable');
|
|
test(map, '# = # - 1', [deferred, variableUseAlias], '--variable');
|
|
test(map, '# = # + 2', [variableUse, variableUseAlias], 'variable += 2');
|
|
test(map, '# = # + 2', [deferred, variableUseAlias], 'variable += 2');
|
|
test(map, '# = # * 2', [variableUse, variableUseAlias], 'variable *= 2');
|
|
test(map, '# = # * 2', [deferred, variableUseAlias], 'variable *= 2');
|
|
|
|
test(map, '# += # + 1', [variableUse, variableUseAlias],
|
|
'variable += variable + 1');
|
|
test(map, '# += # + 1', [deferred, variableUseAlias],
|
|
'variable += variable + 1');
|
|
test(map, '# += # - 1', [variableUse, variableUseAlias],
|
|
'variable += variable - 1');
|
|
test(map, '# += # - 1', [deferred, variableUseAlias],
|
|
'variable += variable - 1');
|
|
test(map, '# += # + 2', [variableUse, variableUseAlias],
|
|
'variable += variable + 2');
|
|
test(map, '# += # + 2', [deferred, variableUseAlias],
|
|
'variable += variable + 2');
|
|
test(map, '# += # * 2', [variableUse, variableUseAlias],
|
|
'variable += variable * 2');
|
|
test(map, '# += # * 2', [deferred, variableUseAlias],
|
|
'variable += variable * 2');
|
|
}
|
|
|
|
void test(Map<Expression, DeferredExpression> map, String template,
|
|
List<Expression> arguments, String expectedOutput) {
|
|
Expression directExpression =
|
|
js.expressionTemplateFor(template).instantiate(arguments);
|
|
_Context directContext = new _Context();
|
|
Printer directPrinter =
|
|
new Printer(const JavaScriptPrintingOptions(), directContext);
|
|
directPrinter.visit(directExpression);
|
|
Expect.equals(expectedOutput, directContext.text);
|
|
|
|
Expression deferredExpression = js
|
|
.expressionTemplateFor(template)
|
|
.instantiate(arguments.map((e) => map[e]).toList());
|
|
_Context deferredContext = new _Context();
|
|
Printer deferredPrinter =
|
|
new Printer(const JavaScriptPrintingOptions(), deferredContext);
|
|
deferredPrinter.visit(deferredExpression);
|
|
Expect.equals(expectedOutput, deferredContext.text);
|
|
|
|
for (Expression argument in arguments) {
|
|
DeferredExpression deferred = map[argument];
|
|
Expect.isTrue(
|
|
directContext.enterPositions.containsKey(argument),
|
|
"Argument ${DebugPrint(argument)} not found in direct enter positions: "
|
|
"${directContext.enterPositions.keys}");
|
|
Expect.isTrue(
|
|
deferredContext.enterPositions.containsKey(argument),
|
|
"Argument ${DebugPrint(argument)} not found in "
|
|
"deferred enter positions: "
|
|
"${deferredContext.enterPositions.keys}");
|
|
Expect.isTrue(
|
|
deferredContext.enterPositions.containsKey(deferred),
|
|
"Argument ${DebugPrint(deferred)} not found in "
|
|
"deferred enter positions: "
|
|
"${deferredContext.enterPositions.keys}");
|
|
Expect.equals(directContext.enterPositions[argument],
|
|
deferredContext.enterPositions[argument]);
|
|
Expect.equals(directContext.enterPositions[argument],
|
|
deferredContext.enterPositions[deferred]);
|
|
|
|
Expect.isTrue(
|
|
directContext.exitPositions.containsKey(argument),
|
|
"Argument ${DebugPrint(argument)} not found in direct enter positions: "
|
|
"${directContext.exitPositions.keys}");
|
|
Expect.isTrue(
|
|
deferredContext.exitPositions.containsKey(argument),
|
|
"Argument ${DebugPrint(argument)} not found in "
|
|
"deferred enter positions: "
|
|
"${deferredContext.exitPositions.keys}");
|
|
Expect.isTrue(
|
|
deferredContext.exitPositions.containsKey(deferred),
|
|
"Argument ${DebugPrint(deferred)} not found in "
|
|
"deferred enter positions: "
|
|
"${deferredContext.exitPositions.keys}");
|
|
Expect.equals(directContext.exitPositions[argument],
|
|
deferredContext.exitPositions[argument]);
|
|
Expect.equals(directContext.exitPositions[argument],
|
|
deferredContext.exitPositions[deferred]);
|
|
}
|
|
}
|
|
|
|
class _DeferredExpression extends DeferredExpression {
|
|
final Expression value;
|
|
|
|
_DeferredExpression(this.value);
|
|
|
|
@override
|
|
int get precedenceLevel => value.precedenceLevel;
|
|
}
|
|
|
|
class _Context implements JavaScriptPrintingContext {
|
|
StringBuffer sb = new StringBuffer();
|
|
List<String> errors = [];
|
|
Map<Node, int> enterPositions = {};
|
|
Map<Node, _Position> exitPositions = {};
|
|
|
|
@override
|
|
void emit(String string) {
|
|
sb.write(string);
|
|
}
|
|
|
|
@override
|
|
void enterNode(Node node, int startPosition) {
|
|
enterPositions[node] = startPosition;
|
|
}
|
|
|
|
@override
|
|
void exitNode(
|
|
Node node, int startPosition, int endPosition, int closingPosition) {
|
|
exitPositions[node] =
|
|
new _Position(startPosition, endPosition, closingPosition);
|
|
Expect.equals(enterPositions[node], startPosition);
|
|
}
|
|
|
|
@override
|
|
void error(String message) {
|
|
errors.add(message);
|
|
}
|
|
|
|
String get text => sb.toString();
|
|
}
|
|
|
|
class _Position {
|
|
final int startPosition;
|
|
final int endPosition;
|
|
final int closingPosition;
|
|
|
|
_Position(this.startPosition, this.endPosition, this.closingPosition);
|
|
|
|
int get hashCode =>
|
|
13 * startPosition.hashCode +
|
|
17 * endPosition.hashCode +
|
|
19 * closingPosition.hashCode;
|
|
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) return true;
|
|
return other is _Position &&
|
|
startPosition == other.startPosition &&
|
|
endPosition == other.endPosition &&
|
|
closingPosition == other.closingPosition;
|
|
}
|
|
|
|
String toString() {
|
|
return '_Position(start=$startPosition,'
|
|
'end=$endPosition,closing=$closingPosition)';
|
|
}
|
|
}
|