Generated source mapping through CPS.

BUG=
R=karlklose@google.com

Review URL: https://codereview.chromium.org//1229673006.
This commit is contained in:
Johnni Winther 2015-07-10 15:32:36 +02:00
parent 9a7d77604b
commit 73572dc3f1
15 changed files with 522 additions and 188 deletions

View file

@ -624,12 +624,13 @@ class IrBuilder {
ir.Primitive _buildInvokeSuper(Element target, ir.Primitive _buildInvokeSuper(Element target,
Selector selector, Selector selector,
List<ir.Primitive> arguments) { List<ir.Primitive> arguments,
SourceInformation sourceInformation) {
assert(target.isInstanceMember); assert(target.isInstanceMember);
assert(isOpen); assert(isOpen);
return _continueWithExpression( return _continueWithExpression(
(k) => new ir.InvokeMethodDirectly( (k) => new ir.InvokeMethodDirectly(
buildThis(), target, selector, arguments, k)); buildThis(), target, selector, arguments, k, sourceInformation));
} }
ir.Primitive _buildInvokeDynamic(ir.Primitive receiver, ir.Primitive _buildInvokeDynamic(ir.Primitive receiver,
@ -655,9 +656,11 @@ class IrBuilder {
/// Create a [ir.Constant] from [value] and add it to the CPS term. /// Create a [ir.Constant] from [value] and add it to the CPS term.
ir.Constant buildConstant(ConstantValue value) { ir.Constant buildConstant(ConstantValue value,
{SourceInformation sourceInformation}) {
assert(isOpen); assert(isOpen);
return addPrimitive(new ir.Constant(value)); return addPrimitive(
new ir.Constant(value, sourceInformation: sourceInformation));
} }
/// Create an integer constant and add it to the CPS term. /// Create an integer constant and add it to the CPS term.
@ -793,63 +796,74 @@ class IrBuilder {
/// Create a invocation of the [method] on the super class where the call /// Create a invocation of the [method] on the super class where the call
/// structure is defined [callStructure] and the argument values are defined /// structure is defined [callStructure] and the argument values are defined
/// by [arguments]. /// by [arguments].
ir.Primitive buildSuperMethodInvocation(MethodElement method, ir.Primitive buildSuperMethodInvocation(
CallStructure callStructure, MethodElement method,
List<ir.Primitive> arguments) { CallStructure callStructure,
List<ir.Primitive> arguments,
{SourceInformation sourceInformation}) {
// TODO(johnniwinther): This shouldn't be necessary. // TODO(johnniwinther): This shouldn't be necessary.
SelectorKind kind = Elements.isOperatorName(method.name) SelectorKind kind = Elements.isOperatorName(method.name)
? SelectorKind.OPERATOR : SelectorKind.CALL; ? SelectorKind.OPERATOR : SelectorKind.CALL;
Selector selector = Selector selector =
new Selector(kind, method.memberName, callStructure); new Selector(kind, method.memberName, callStructure);
return _buildInvokeSuper(method, selector, arguments); return _buildInvokeSuper(method, selector, arguments, sourceInformation);
} }
/// Create a read access of the [method] on the super class, i.e. a /// Create a read access of the [method] on the super class, i.e. a
/// closurization of [method]. /// closurization of [method].
ir.Primitive buildSuperMethodGet(MethodElement method) { ir.Primitive buildSuperMethodGet(MethodElement method,
{SourceInformation sourceInformation}) {
// TODO(johnniwinther): This should have its own ir node. // TODO(johnniwinther): This should have its own ir node.
return _buildInvokeSuper( return _buildInvokeSuper(
method, method,
new Selector.getter(method.name, method.library), new Selector.getter(method.name, method.library),
const <ir.Primitive>[]); const <ir.Primitive>[],
sourceInformation);
} }
/// Create a getter invocation of the [getter] on the super class. /// Create a getter invocation of the [getter] on the super class.
ir.Primitive buildSuperGetterGet(MethodElement getter) { ir.Primitive buildSuperGetterGet(MethodElement getter,
SourceInformation sourceInformation) {
// TODO(johnniwinther): This should have its own ir node. // TODO(johnniwinther): This should have its own ir node.
return _buildInvokeSuper( return _buildInvokeSuper(
getter, getter,
new Selector.getter(getter.name, getter.library), new Selector.getter(getter.name, getter.library),
const <ir.Primitive>[]); const <ir.Primitive>[],
sourceInformation);
} }
/// Create an setter invocation of the [setter] on the super class with /// Create an setter invocation of the [setter] on the super class with
/// [value]. /// [value].
ir.Primitive buildSuperSetterSet(MethodElement setter, ir.Primitive buildSuperSetterSet(MethodElement setter,
ir.Primitive value) { ir.Primitive value,
{SourceInformation sourceInformation}) {
// TODO(johnniwinther): This should have its own ir node. // TODO(johnniwinther): This should have its own ir node.
_buildInvokeSuper( _buildInvokeSuper(
setter, setter,
new Selector.setter(setter.name, setter.library), new Selector.setter(setter.name, setter.library),
<ir.Primitive>[value]); <ir.Primitive>[value],
sourceInformation);
return value; return value;
} }
/// Create an invocation of the index [method] on the super class with /// Create an invocation of the index [method] on the super class with
/// the provided [index]. /// the provided [index].
ir.Primitive buildSuperIndex(MethodElement method, ir.Primitive buildSuperIndex(MethodElement method,
ir.Primitive index) { ir.Primitive index,
{SourceInformation sourceInformation}) {
return _buildInvokeSuper( return _buildInvokeSuper(
method, new Selector.index(), <ir.Primitive>[index]); method, new Selector.index(), <ir.Primitive>[index],
sourceInformation);
} }
/// Create an invocation of the index set [method] on the super class with /// Create an invocation of the index set [method] on the super class with
/// the provided [index] and [value]. /// the provided [index] and [value].
ir.Primitive buildSuperIndexSet(MethodElement method, ir.Primitive buildSuperIndexSet(MethodElement method,
ir.Primitive index, ir.Primitive index,
ir.Primitive value) { ir.Primitive value,
{SourceInformation sourceInformation}) {
_buildInvokeSuper(method, new Selector.indexSet(), _buildInvokeSuper(method, new Selector.indexSet(),
<ir.Primitive>[index, value]); <ir.Primitive>[index, value], sourceInformation);
return value; return value;
} }
@ -859,8 +873,11 @@ class IrBuilder {
ir.Primitive buildDynamicInvocation(ir.Primitive receiver, ir.Primitive buildDynamicInvocation(ir.Primitive receiver,
Selector selector, Selector selector,
TypeMask mask, TypeMask mask,
List<ir.Primitive> arguments) { List<ir.Primitive> arguments,
return _buildInvokeDynamic(receiver, selector, mask, arguments); {SourceInformation sourceInformation}) {
return _buildInvokeDynamic(
receiver, selector, mask, arguments,
sourceInformation: sourceInformation);
} }
/// Create a dynamic getter invocation on [receiver] where the getter name is /// Create a dynamic getter invocation on [receiver] where the getter name is
@ -925,11 +942,14 @@ class IrBuilder {
/// Create an invocation of the the [local] variable or parameter where /// Create an invocation of the the [local] variable or parameter where
/// argument structure is defined by [callStructure] and the argument values /// argument structure is defined by [callStructure] and the argument values
/// are defined by [arguments]. /// are defined by [arguments].
ir.Primitive buildLocalVariableInvocation(LocalVariableElement local, ir.Primitive buildLocalVariableInvocation(
CallStructure callStructure, LocalVariableElement local,
List<ir.Primitive> arguments) { CallStructure callStructure,
List<ir.Primitive> arguments,
{SourceInformation callSourceInformation}) {
return buildCallInvocation( return buildCallInvocation(
buildLocalVariableGet(local), callStructure, arguments); buildLocalVariableGet(local), callStructure, arguments,
sourceInformation: callSourceInformation);
} }
/// Create an invocation of the local [function] where argument structure is /// Create an invocation of the local [function] where argument structure is
@ -938,10 +958,12 @@ class IrBuilder {
ir.Primitive buildLocalFunctionInvocation( ir.Primitive buildLocalFunctionInvocation(
LocalFunctionElement function, LocalFunctionElement function,
CallStructure callStructure, CallStructure callStructure,
List<ir.Primitive> arguments) { List<ir.Primitive> arguments,
SourceInformation sourceInformation) {
// TODO(johnniwinther): Maybe this should have its own ir node. // TODO(johnniwinther): Maybe this should have its own ir node.
return buildCallInvocation( return buildCallInvocation(
buildLocalFunctionGet(function), callStructure, arguments); buildLocalFunctionGet(function), callStructure, arguments,
sourceInformation: sourceInformation);
} }
/// Create a static invocation of [function] where argument structure is /// Create a static invocation of [function] where argument structure is
@ -974,7 +996,7 @@ class IrBuilder {
/// Create a getter invocation of the static [getter]. /// Create a getter invocation of the static [getter].
ir.Primitive buildStaticGetterGet(MethodElement getter, ir.Primitive buildStaticGetterGet(MethodElement getter,
{SourceInformation sourceInformation}) { SourceInformation sourceInformation) {
Selector selector = new Selector.getter(getter.name, getter.library); Selector selector = new Selector.getter(getter.name, getter.library);
return _buildInvokeStatic( return _buildInvokeStatic(
getter, selector, const <ir.Primitive>[], sourceInformation); getter, selector, const <ir.Primitive>[], sourceInformation);
@ -1958,7 +1980,7 @@ class IrBuilder {
IrBuilder builder = makeDelimitedBuilder(newReturn.environment); IrBuilder builder = makeDelimitedBuilder(newReturn.environment);
ir.Primitive value = builder.environment.discard(1); ir.Primitive value = builder.environment.discard(1);
buildFinallyBlock(builder); buildFinallyBlock(builder);
if (builder.isOpen) builder.buildReturn(value); if (builder.isOpen) builder.buildReturn(value: value);
newReturn.continuation.body = builder._root; newReturn.continuation.body = builder._root;
exits.add(newReturn.continuation); exits.add(newReturn.continuation);
} }
@ -1973,7 +1995,7 @@ class IrBuilder {
/// Create a return statement `return value;` or `return;` if [value] is /// Create a return statement `return value;` or `return;` if [value] is
/// null. /// null.
void buildReturn([ir.Primitive value]) { void buildReturn({ir.Primitive value, SourceInformation sourceInformation}) {
// Build(Return(e), C) = C'[InvokeContinuation(return, x)] // Build(Return(e), C) = C'[InvokeContinuation(return, x)]
// where (C', x) = Build(e, C) // where (C', x) = Build(e, C)
// //
@ -1983,7 +2005,8 @@ class IrBuilder {
value = buildNullConstant(); value = buildNullConstant();
} }
if (state.returnCollector == null) { if (state.returnCollector == null) {
add(new ir.InvokeContinuation(state.returnContinuation, [value])); add(new ir.InvokeContinuation(state.returnContinuation, [value],
sourceInformation: sourceInformation));
_current = null; _current = null;
} else { } else {
// Inside the try block of try/finally, all returns go to a join-point // Inside the try block of try/finally, all returns go to a join-point
@ -2305,12 +2328,15 @@ class IrBuilder {
/// Add [functionElement] to the environment with provided [definition]. /// Add [functionElement] to the environment with provided [definition].
void declareLocalFunction(LocalFunctionElement functionElement, void declareLocalFunction(LocalFunctionElement functionElement,
ClosureClassElement classElement) { ClosureClassElement classElement,
ir.Primitive closure = buildFunctionExpression(classElement); SourceInformation sourceInformation) {
ir.Primitive closure =
buildFunctionExpression(classElement, sourceInformation);
declareLocalVariable(functionElement, initialValue: closure); declareLocalVariable(functionElement, initialValue: closure);
} }
ir.Primitive buildFunctionExpression(ClosureClassElement classElement) { ir.Primitive buildFunctionExpression(ClosureClassElement classElement,
SourceInformation sourceInformation) {
List<ir.Primitive> arguments = <ir.Primitive>[]; List<ir.Primitive> arguments = <ir.Primitive>[];
for (ClosureFieldElement field in classElement.closureFields) { for (ClosureFieldElement field in classElement.closureFields) {
// Captured 'this' is not available as a local in the current environment, // Captured 'this' is not available as a local in the current environment,
@ -2320,8 +2346,8 @@ class IrBuilder {
: environment.lookup(field.local); : environment.lookup(field.local);
arguments.add(value); arguments.add(value);
} }
return addPrimitive( return addPrimitive(new ir.CreateInstance(
new ir.CreateInstance(classElement, arguments, const <ir.Primitive>[])); classElement, arguments, const <ir.Primitive>[], sourceInformation));
} }
/// Create a read access of [local] variable or parameter. /// Create a read access of [local] variable or parameter.
@ -2430,13 +2456,14 @@ class IrBuilder {
ir.Primitive buildInvokeDirectly(FunctionElement target, ir.Primitive buildInvokeDirectly(FunctionElement target,
ir.Primitive receiver, ir.Primitive receiver,
List<ir.Primitive> arguments) { List<ir.Primitive> arguments,
{SourceInformation sourceInformation}) {
assert(isOpen); assert(isOpen);
Selector selector = Selector selector =
new Selector.call(target.name, target.library, arguments.length); new Selector.call(target.name, target.library, arguments.length);
return _continueWithExpression( return _continueWithExpression(
(k) => new ir.InvokeMethodDirectly( (k) => new ir.InvokeMethodDirectly(
receiver, target, selector, arguments, k)); receiver, target, selector, arguments, k, sourceInformation));
} }
/// Loads parameters to a constructor body into the environment. /// Loads parameters to a constructor body into the environment.
@ -2459,10 +2486,12 @@ class IrBuilder {
/// Create a constructor invocation of [element] on [type] where the /// Create a constructor invocation of [element] on [type] where the
/// constructor name and argument structure are defined by [callStructure] and /// constructor name and argument structure are defined by [callStructure] and
/// the argument values are defined by [arguments]. /// the argument values are defined by [arguments].
ir.Primitive buildConstructorInvocation(ConstructorElement element, ir.Primitive buildConstructorInvocation(
CallStructure callStructure, ConstructorElement element,
DartType type, CallStructure callStructure,
List<ir.Primitive> arguments) { DartType type,
List<ir.Primitive> arguments,
SourceInformation sourceInformation) {
assert(isOpen); assert(isOpen);
Selector selector = Selector selector =
new Selector(SelectorKind.CALL, element.memberName, callStructure); new Selector(SelectorKind.CALL, element.memberName, callStructure);
@ -2479,8 +2508,8 @@ class IrBuilder {
..addAll(typeArguments); ..addAll(typeArguments);
} }
return _continueWithExpression( return _continueWithExpression(
(k) => new ir.InvokeConstructor(type, element, selector, (k) => new ir.InvokeConstructor(
arguments, k)); type, element, selector, arguments, k, sourceInformation));
} }
ir.Primitive buildTypeExpression(DartType type) { ir.Primitive buildTypeExpression(DartType type) {
@ -2508,7 +2537,8 @@ class IrBuilder {
/// if we are currently building a constructor field initializer, from the /// if we are currently building a constructor field initializer, from the
/// corresponding type argument (field initializers are evaluated before the /// corresponding type argument (field initializers are evaluated before the
/// receiver object is created). /// receiver object is created).
ir.Primitive buildTypeVariableAccess(TypeVariableType variable) { ir.Primitive buildTypeVariableAccess(TypeVariableType variable,
{SourceInformation sourceInformation}) {
// If the local exists in the environment, use that. // If the local exists in the environment, use that.
// This is put here when we are inside a constructor or field initializer, // This is put here when we are inside a constructor or field initializer,
// (or possibly a closure inside one of these). // (or possibly a closure inside one of these).
@ -2520,7 +2550,8 @@ class IrBuilder {
// If the type variable is not in a local, read its value from the // If the type variable is not in a local, read its value from the
// receiver object. // receiver object.
ir.Primitive target = buildThis(); ir.Primitive target = buildThis();
return addPrimitive(new ir.ReadTypeVariable(variable, target)); return addPrimitive(
new ir.ReadTypeVariable(variable, target, sourceInformation));
} }
/// Make the given type variable accessible through the local environment /// Make the given type variable accessible through the local environment
@ -2532,9 +2563,12 @@ class IrBuilder {
} }
/// Reifies the value of [variable] on the current receiver object. /// Reifies the value of [variable] on the current receiver object.
ir.Primitive buildReifyTypeVariable(TypeVariableType variable) { ir.Primitive buildReifyTypeVariable(TypeVariableType variable,
ir.Primitive typeArgument = buildTypeVariableAccess(variable); SourceInformation sourceInformation) {
return addPrimitive(new ir.ReifyRuntimeType(typeArgument)); ir.Primitive typeArgument =
buildTypeVariableAccess(variable, sourceInformation: sourceInformation);
return addPrimitive(
new ir.ReifyRuntimeType(typeArgument, sourceInformation));
} }
ir.Primitive buildInvocationMirror(Selector selector, ir.Primitive buildInvocationMirror(Selector selector,

View file

@ -284,8 +284,11 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
targetConstructor, targetConstructor,
callStructure, callStructure,
targetType, targetType,
arguments); arguments,
irBuilder.buildReturn(instance); sourceInformationBuilder.buildNew(node));
irBuilder.buildReturn(
value: instance,
sourceInformation: sourceInformationBuilder.buildReturn(node));
} }
visitFor(ast.For node) { visitFor(ast.For node) {
@ -399,7 +402,9 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
ir.Primitive visitReturn(ast.Return node) { ir.Primitive visitReturn(ast.Return node) {
assert(irBuilder.isOpen); assert(irBuilder.isOpen);
assert(invariant(node, node.beginToken.value != 'native')); assert(invariant(node, node.beginToken.value != 'native'));
irBuilder.buildReturn(build(node.expression)); irBuilder.buildReturn(
value: build(node.expression),
sourceInformation: sourceInformationBuilder.buildReturn(node));
return null; return null;
} }
@ -533,9 +538,11 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
return irBuilder.state.constants.getConstantValueForVariable(element); return irBuilder.state.constants.getConstantValueForVariable(element);
} }
ir.Primitive buildConstantExpression(ConstantExpression expression) { ir.Primitive buildConstantExpression(ConstantExpression expression,
SourceInformation sourceInformation) {
return irBuilder.buildConstant( return irBuilder.buildConstant(
irBuilder.state.constants.getConstantValue(expression)); irBuilder.state.constants.getConstantValue(expression),
sourceInformation: sourceInformation);
} }
ir.Primitive visitLiteralList(ast.LiteralList node) { ir.Primitive visitLiteralList(ast.LiteralList node) {
@ -599,7 +606,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
} else { } else {
// The call to assert and its argument expression must be ignored // The call to assert and its argument expression must be ignored
// in production mode. // in production mode.
// Assertions can only occur in expression statements, so no value needs // Assertions can onl)y occur in expression statements, so no value needs
// to be returned. // to be returned.
return null; return null;
} }
@ -613,13 +620,15 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
@override @override
ir.Primitive visitExpressionInvoke(ast.Send node, ir.Primitive visitExpressionInvoke(ast.Send node,
ast.Node expression, ast.Node expression,
ast.NodeList arguments, ast.NodeList argumentsNode,
Selector selector, _) { Selector selector, _) {
ir.Primitive receiver = visit(expression); ir.Primitive receiver = visit(expression);
List<ir.Primitive> arguments = node.arguments.mapToList(visit); List<ir.Primitive> arguments = node.arguments.mapToList(visit);
arguments = normalizeDynamicArguments(selector.callStructure, arguments); arguments = normalizeDynamicArguments(selector.callStructure, arguments);
return irBuilder.buildCallInvocation( return irBuilder.buildCallInvocation(
receiver, selector.callStructure, arguments); receiver, selector.callStructure, arguments,
sourceInformation:
sourceInformationBuilder.buildCall(node, argumentsNode));
} }
/// Returns `true` if [node] is a super call. /// Returns `true` if [node] is a super call.
@ -632,7 +641,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
ir.Primitive handleConstantGet( ir.Primitive handleConstantGet(
ast.Node node, ast.Node node,
ConstantExpression constant, _) { ConstantExpression constant, _) {
return buildConstantExpression(constant); return buildConstantExpression(constant,
sourceInformationBuilder.buildGet(node));
} }
/// If [node] is null, returns this. /// If [node] is null, returns this.
@ -671,7 +681,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
ast.Send node, ast.Send node,
ConstantExpression constant, ConstantExpression constant,
_) { _) {
return buildConstantExpression(constant); return buildConstantExpression(constant,
sourceInformationBuilder.buildGet(node));
} }
@override @override
@ -680,7 +691,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
LocalVariableElement element, LocalVariableElement element,
_) { _) {
return element.isConst return element.isConst
? irBuilder.buildConstant(getConstantForVariable(element)) ? irBuilder.buildConstant(getConstantForVariable(element),
sourceInformation: sourceInformationBuilder.buildGet(node))
: irBuilder.buildLocalVariableGet(element); : irBuilder.buildLocalVariableGet(element);
} }
@ -717,7 +729,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
ast.Send node, ast.Send node,
FunctionElement getter, FunctionElement getter,
_) { _) {
return irBuilder.buildStaticGetterGet(getter); return irBuilder.buildStaticGetterGet(
getter, sourceInformationBuilder.buildGet(node));
} }
@override @override
@ -733,7 +746,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
ast.Send node, ast.Send node,
FunctionElement getter, FunctionElement getter,
_) { _) {
return irBuilder.buildSuperGetterGet(getter); return irBuilder.buildSuperGetterGet(
getter, sourceInformationBuilder.buildGet(node));
} }
@override @override
@ -763,14 +777,17 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
return irBuilder.buildThis(); return irBuilder.buildThis();
} }
ir.Primitive translateTypeVariableTypeLiteral(TypeVariableElement element) { ir.Primitive translateTypeVariableTypeLiteral(
return irBuilder.buildReifyTypeVariable(element.type); TypeVariableElement element,
SourceInformation sourceInformation) {
return irBuilder.buildReifyTypeVariable(element.type, sourceInformation);
} }
@override @override
ir.Primitive visitTypeVariableTypeLiteralGet(ast.Send node, ir.Primitive visitTypeVariableTypeLiteralGet(ast.Send node,
TypeVariableElement element, _) { TypeVariableElement element, _) {
return translateTypeVariableTypeLiteral(element); return translateTypeVariableTypeLiteral(element,
sourceInformationBuilder.buildGet(node));
} }
ir.Primitive translateLogicalOperator(ast.Expression left, ir.Primitive translateLogicalOperator(ast.Expression left,
@ -842,7 +859,9 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
List<ir.Primitive> arguments = <ir.Primitive>[visit(right)]; List<ir.Primitive> arguments = <ir.Primitive>[visit(right)];
arguments = normalizeDynamicArguments(selector.callStructure, arguments); arguments = normalizeDynamicArguments(selector.callStructure, arguments);
return irBuilder.buildDynamicInvocation( return irBuilder.buildDynamicInvocation(
receiver, selector, elements.getTypeMask(node), arguments); receiver, selector, elements.getTypeMask(node), arguments,
sourceInformation:
sourceInformationBuilder.buildCall(node, node.selector));
} }
@override @override
@ -979,10 +998,12 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
ir.Primitive translateCallInvoke(ir.Primitive target, ir.Primitive translateCallInvoke(ir.Primitive target,
ast.NodeList arguments, ast.NodeList arguments,
CallStructure callStructure) { CallStructure callStructure,
SourceInformation sourceInformation) {
return irBuilder.buildCallInvocation(target, callStructure, return irBuilder.buildCallInvocation(target, callStructure,
translateDynamicArguments(arguments, callStructure)); translateDynamicArguments(arguments, callStructure),
sourceInformation: sourceInformation);
} }
@override @override
@ -992,8 +1013,10 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
ast.NodeList arguments, ast.NodeList arguments,
CallStructure callStructure, CallStructure callStructure,
_) { _) {
ir.Primitive target = buildConstantExpression(constant); ir.Primitive target = buildConstantExpression(constant,
return translateCallInvoke(target, arguments, callStructure); sourceInformationBuilder.buildGet(node));
return translateCallInvoke(target, arguments, callStructure,
sourceInformationBuilder.buildCall(node, arguments));
} }
@override @override
@ -1005,7 +1028,9 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
_) { _) {
return irBuilder.buildDynamicInvocation( return irBuilder.buildDynamicInvocation(
translateReceiver(receiver), selector, elements.getTypeMask(node), translateReceiver(receiver), selector, elements.getTypeMask(node),
translateDynamicArguments(arguments, selector.callStructure)); translateDynamicArguments(arguments, selector.callStructure),
sourceInformation:
sourceInformationBuilder.buildCall(node, node.selector));
} }
@override @override
@ -1030,7 +1055,9 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
CallStructure callStructure, CallStructure callStructure,
_) { _) {
return irBuilder.buildLocalVariableInvocation(element, callStructure, return irBuilder.buildLocalVariableInvocation(element, callStructure,
translateDynamicArguments(arguments, callStructure)); translateDynamicArguments(arguments, callStructure),
callSourceInformation:
sourceInformationBuilder.buildCall(node, arguments));
} }
@override @override
@ -1041,7 +1068,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
CallStructure callStructure, CallStructure callStructure,
_) { _) {
return irBuilder.buildLocalFunctionInvocation(function, callStructure, return irBuilder.buildLocalFunctionInvocation(function, callStructure,
translateDynamicArguments(arguments, callStructure)); translateDynamicArguments(arguments, callStructure),
sourceInformationBuilder.buildCall(node, arguments));
} }
@override @override
@ -1060,7 +1088,9 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
ir.Primitive target = buildStaticFieldGet(field, src); ir.Primitive target = buildStaticFieldGet(field, src);
return irBuilder.buildCallInvocation(target, return irBuilder.buildCallInvocation(target,
callStructure, callStructure,
translateDynamicArguments(arguments, callStructure)); translateDynamicArguments(arguments, callStructure),
sourceInformation:
sourceInformationBuilder.buildCall(node, arguments));
} }
@override @override
@ -1092,10 +1122,13 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
if (compiler.backend.isForeign(getter)) { if (compiler.backend.isForeign(getter)) {
return giveup(node, 'handleStaticGetterInvoke: foreign: $getter'); return giveup(node, 'handleStaticGetterInvoke: foreign: $getter');
} }
ir.Primitive target = irBuilder.buildStaticGetterGet(getter); ir.Primitive target = irBuilder.buildStaticGetterGet(
getter, sourceInformationBuilder.buildGet(node));
return irBuilder.buildCallInvocation(target, return irBuilder.buildCallInvocation(target,
callStructure, callStructure,
translateDynamicArguments(arguments, callStructure)); translateDynamicArguments(arguments, callStructure),
sourceInformation:
sourceInformationBuilder.buildCall(node, arguments));
} }
@override @override
@ -1108,7 +1141,9 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
ir.Primitive target = irBuilder.buildSuperFieldGet(field); ir.Primitive target = irBuilder.buildSuperFieldGet(field);
return irBuilder.buildCallInvocation(target, return irBuilder.buildCallInvocation(target,
callStructure, callStructure,
translateDynamicArguments(arguments, callStructure)); translateDynamicArguments(arguments, callStructure),
sourceInformation:
sourceInformationBuilder.buildCall(node, arguments));
} }
@override @override
@ -1118,10 +1153,13 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
ast.NodeList arguments, ast.NodeList arguments,
CallStructure callStructure, CallStructure callStructure,
_) { _) {
ir.Primitive target = irBuilder.buildSuperGetterGet(getter); ir.Primitive target = irBuilder.buildSuperGetterGet(
getter, sourceInformationBuilder.buildGet(node));
return irBuilder.buildCallInvocation(target, return irBuilder.buildCallInvocation(target,
callStructure, callStructure,
translateDynamicArguments(arguments, callStructure)); translateDynamicArguments(arguments, callStructure),
sourceInformation:
sourceInformationBuilder.buildCall(node, arguments));
} }
@override @override
@ -1132,7 +1170,9 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
CallStructure callStructure, CallStructure callStructure,
_) { _) {
return irBuilder.buildSuperMethodInvocation(method, callStructure, return irBuilder.buildSuperMethodInvocation(method, callStructure,
translateDynamicArguments(arguments, callStructure)); translateDynamicArguments(arguments, callStructure),
sourceInformation:
sourceInformationBuilder.buildCall(node, node.selector));
} }
@override @override
@ -1165,7 +1205,11 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
ast.NodeList arguments, ast.NodeList arguments,
CallStructure callStructure, CallStructure callStructure,
_) { _) {
return translateCallInvoke(irBuilder.buildThis(), arguments, callStructure); return translateCallInvoke(
irBuilder.buildThis(),
arguments,
callStructure,
sourceInformationBuilder.buildCall(node, arguments));
} }
@override @override
@ -1176,9 +1220,11 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
CallStructure callStructure, CallStructure callStructure,
_) { _) {
return translateCallInvoke( return translateCallInvoke(
translateTypeVariableTypeLiteral(element), translateTypeVariableTypeLiteral(
element, sourceInformationBuilder.buildGet(node)),
arguments, arguments,
callStructure); callStructure,
sourceInformationBuilder.buildCall(node, arguments));
} }
@override @override
@ -1327,7 +1373,10 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
CompoundRhs rhs, CompoundRhs rhs,
arg) { arg) {
return translateCompounds( return translateCompounds(
getValue: () => buildConstantExpression(constant), getValue: () {
return buildConstantExpression(constant,
sourceInformationBuilder.buildGet(node));
},
rhs: rhs, rhs: rhs,
setValue: (value) {}, // The binary operator will throw before this. setValue: (value) {}, // The binary operator will throw before this.
operatorTypeMask: elements.getOperatorTypeMaskInComplexSendSet(node)); operatorTypeMask: elements.getOperatorTypeMaskInComplexSendSet(node));
@ -1419,7 +1468,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
SourceInformation src = sourceInformationBuilder.buildGet(node); SourceInformation src = sourceInformationBuilder.buildGet(node);
return irBuilder.buildStaticFieldGet(getter, src); return irBuilder.buildStaticFieldGet(getter, src);
case CompoundGetter.GETTER: case CompoundGetter.GETTER:
return irBuilder.buildStaticGetterGet(getter); return irBuilder.buildStaticGetterGet(
getter, sourceInformationBuilder.buildGet(node));
case CompoundGetter.METHOD: case CompoundGetter.METHOD:
return irBuilder.buildStaticFunctionGet(getter); return irBuilder.buildStaticFunctionGet(getter);
case CompoundGetter.UNRESOLVED: case CompoundGetter.UNRESOLVED:
@ -1473,7 +1523,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
case CompoundGetter.FIELD: case CompoundGetter.FIELD:
return irBuilder.buildSuperFieldGet(getter); return irBuilder.buildSuperFieldGet(getter);
case CompoundGetter.GETTER: case CompoundGetter.GETTER:
return irBuilder.buildSuperGetterGet(getter); return irBuilder.buildSuperGetterGet(
getter, sourceInformationBuilder.buildGet(node));
case CompoundGetter.METHOD: case CompoundGetter.METHOD:
return irBuilder.buildSuperMethodGet(getter); return irBuilder.buildSuperMethodGet(getter);
case CompoundGetter.UNRESOLVED: case CompoundGetter.UNRESOLVED:
@ -1505,7 +1556,11 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
CompoundRhs rhs, CompoundRhs rhs,
arg) { arg) {
return translateCompounds( return translateCompounds(
getValue: () => irBuilder.buildReifyTypeVariable(typeVariable.type), getValue: () {
return irBuilder.buildReifyTypeVariable(
typeVariable.type,
sourceInformationBuilder.buildGet(node));
},
rhs: rhs, rhs: rhs,
setValue: (value) {}, // The binary operator will throw before this. setValue: (value) {}, // The binary operator will throw before this.
operatorTypeMask: elements.getOperatorTypeMaskInComplexSendSet(node)); operatorTypeMask: elements.getOperatorTypeMaskInComplexSendSet(node));
@ -1621,7 +1676,9 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
ir.Primitive translateConstant(ast.Node node) { ir.Primitive translateConstant(ast.Node node) {
assert(irBuilder.isOpen); assert(irBuilder.isOpen);
return irBuilder.buildConstant(getConstantForNode(node)); return irBuilder.buildConstant(
getConstantForNode(node),
sourceInformation: sourceInformationBuilder.buildGet(node));
} }
ir.Primitive visitThrow(ast.Throw node) { ir.Primitive visitThrow(ast.Throw node) {
@ -2255,13 +2312,15 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
} }
ir.Primitive visitFunctionExpression(ast.FunctionExpression node) { ir.Primitive visitFunctionExpression(ast.FunctionExpression node) {
return irBuilder.buildFunctionExpression(makeSubFunction(node)); return irBuilder.buildFunctionExpression(makeSubFunction(node),
sourceInformationBuilder.buildCreate(node));
} }
visitFunctionDeclaration(ast.FunctionDeclaration node) { visitFunctionDeclaration(ast.FunctionDeclaration node) {
LocalFunctionElement element = elements[node.function]; LocalFunctionElement element = elements[node.function];
Object inner = makeSubFunction(node.function); Object inner = makeSubFunction(node.function);
irBuilder.declareLocalFunction(element, inner); irBuilder.declareLocalFunction(element, inner,
sourceInformationBuilder.buildCreate(node.function));
} }
Map mapValues(Map map, dynamic fn(dynamic)) { Map mapValues(Map map, dynamic fn(dynamic)) {
@ -2376,7 +2435,12 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
return withBuilder(builder, () { return withBuilder(builder, () {
irBuilder.buildFunctionHeader(<Local>[]); irBuilder.buildFunctionHeader(<Local>[]);
ir.Primitive initialValue = visit(element.initializer); ir.Primitive initialValue = visit(element.initializer);
irBuilder.buildReturn(initialValue); ast.VariableDefinitions node = element.node;
ast.SendSet sendSet = node.definitions.nodes.head;
irBuilder.buildReturn(
value: initialValue,
sourceInformation:
sourceInformationBuilder.buildReturn(sendSet.assignmentOperator));
return irBuilder.makeFunctionDefinition(); return irBuilder.makeFunctionDefinition();
}); });
} }
@ -2501,10 +2565,16 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
// Native fields are initialized elsewhere. // Native fields are initialized elsewhere.
} }
}, includeSuperAndInjectedMembers: true); }, includeSuperAndInjectedMembers: true);
ir.Primitive instance = new ir.CreateInstance( ir.Primitive instance = new ir.CreateInstance(
classElement, classElement,
instanceArguments, instanceArguments,
typeInformation); typeInformation,
constructor.hasNode
? sourceInformationBuilder.buildCreate(constructor.node)
// TODO(johnniwinther): Provide source information for creation
// through synthetic constructors.
: null);
irBuilder.add(new ir.LetPrim(instance)); irBuilder.add(new ir.LetPrim(instance));
// --- Call constructor bodies --- // --- Call constructor bodies ---
@ -2519,7 +2589,10 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
} }
// --- step 4: return the created object ---- // --- step 4: return the created object ----
irBuilder.buildReturn(instance); irBuilder.buildReturn(
value: instance,
sourceInformation:
sourceInformationBuilder.buildImplicitReturn(constructor));
return irBuilder.makeFunctionDefinition(); return irBuilder.makeFunctionDefinition();
}); });
@ -2974,7 +3047,8 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
target, target,
callStructure, callStructure,
constructor.computeEffectiveTargetType(type), constructor.computeEffectiveTargetType(type),
arguments); arguments,
sourceInformationBuilder.buildNew(node));
} }
@override @override
@ -3027,7 +3101,7 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) { ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) {
ConstantValue constant = getConstantForVariable(field); ConstantValue constant = getConstantForVariable(field);
if (constant != null && !field.isAssignable) { if (constant != null && !field.isAssignable) {
return irBuilder.buildConstant(constant); return irBuilder.buildConstant(constant, sourceInformation: src);
} else if (backend.constants.lazyStatics.contains(field)) { } else if (backend.constants.lazyStatics.contains(field)) {
return irBuilder.buildStaticFieldLazyGet(field, src); return irBuilder.buildStaticFieldLazyGet(field, src);
} else { } else {

View file

@ -344,12 +344,14 @@ class InvokeMethodDirectly extends Expression implements Invoke {
final Selector selector; final Selector selector;
final List<Reference<Primitive>> arguments; final List<Reference<Primitive>> arguments;
final Reference<Continuation> continuation; final Reference<Continuation> continuation;
final SourceInformation sourceInformation;
InvokeMethodDirectly(Primitive receiver, InvokeMethodDirectly(Primitive receiver,
this.target, this.target,
this.selector, this.selector,
List<Primitive> arguments, List<Primitive> arguments,
Continuation continuation) Continuation continuation,
this.sourceInformation)
: this.receiver = new Reference<Primitive>(receiver), : this.receiver = new Reference<Primitive>(receiver),
this.arguments = _referenceList(arguments), this.arguments = _referenceList(arguments),
this.continuation = new Reference<Continuation>(continuation); this.continuation = new Reference<Continuation>(continuation);
@ -378,12 +380,14 @@ class InvokeConstructor extends Expression implements Invoke {
final List<Reference<Primitive>> arguments; final List<Reference<Primitive>> arguments;
final Reference<Continuation> continuation; final Reference<Continuation> continuation;
final Selector selector; final Selector selector;
final SourceInformation sourceInformation;
InvokeConstructor(this.type, InvokeConstructor(this.type,
this.target, this.target,
this.selector, this.selector,
List<Primitive> args, List<Primitive> args,
Continuation cont) Continuation cont,
this.sourceInformation)
: arguments = _referenceList(args), : arguments = _referenceList(args),
continuation = new Reference<Continuation>(cont); continuation = new Reference<Continuation>(cont);
@ -563,6 +567,7 @@ class SetMutableVariable extends Expression implements InteriorNode {
class InvokeContinuation extends Expression { class InvokeContinuation extends Expression {
Reference<Continuation> continuation; Reference<Continuation> continuation;
List<Reference<Primitive>> arguments; List<Reference<Primitive>> arguments;
SourceInformation sourceInformation;
// An invocation of a continuation is recursive if it occurs in the body of // An invocation of a continuation is recursive if it occurs in the body of
// the continuation itself. // the continuation itself.
@ -574,7 +579,8 @@ class InvokeContinuation extends Expression {
InvokeContinuation(Continuation cont, List<Primitive> args, InvokeContinuation(Continuation cont, List<Primitive> args,
{this.isRecursive: false, {this.isRecursive: false,
this.isEscapingTry: false}) this.isEscapingTry: false,
this.sourceInformation})
: continuation = new Reference<Continuation>(cont), : continuation = new Reference<Continuation>(cont),
arguments = _referenceList(args) { arguments = _referenceList(args) {
assert(cont.parameters == null || cont.parameters.length == args.length); assert(cont.parameters == null || cont.parameters.length == args.length);
@ -586,10 +592,11 @@ class InvokeContinuation extends Expression {
/// ///
/// Used as a placeholder for a jump whose target is not yet created /// Used as a placeholder for a jump whose target is not yet created
/// (e.g., in the translation of break and continue). /// (e.g., in the translation of break and continue).
InvokeContinuation.uninitialized({this.isRecursive: false, InvokeContinuation.uninitialized({this.isRecursive: false,
this.isEscapingTry: false}) this.isEscapingTry: false})
: continuation = null, : continuation = null,
arguments = null; arguments = null,
sourceInformation = null;
accept(Visitor visitor) => visitor.visitInvokeContinuation(this); accept(Visitor visitor) => visitor.visitInvokeContinuation(this);
} }
@ -798,8 +805,11 @@ class CreateInstance extends Primitive {
/// is not needed at runtime. /// is not needed at runtime.
final List<Reference<Primitive>> typeInformation; final List<Reference<Primitive>> typeInformation;
final SourceInformation sourceInformation;
CreateInstance(this.classElement, List<Primitive> arguments, CreateInstance(this.classElement, List<Primitive> arguments,
List<Primitive> typeInformation) List<Primitive> typeInformation,
this.sourceInformation)
: this.arguments = _referenceList(arguments), : this.arguments = _referenceList(arguments),
this.typeInformation = _referenceList(typeInformation); this.typeInformation = _referenceList(typeInformation);
@ -856,8 +866,9 @@ class ForeignCode extends Expression {
class Constant extends Primitive { class Constant extends Primitive {
final values.ConstantValue value; final values.ConstantValue value;
final SourceInformation sourceInformation;
Constant(this.value); Constant(this.value, {this.sourceInformation});
accept(Visitor visitor) => visitor.visitConstant(this); accept(Visitor visitor) => visitor.visitConstant(this);
@ -959,7 +970,7 @@ class Continuation extends Definition<Continuation> implements InteriorNode {
Continuation(this.parameters, {this.isRecursive: false}); Continuation(this.parameters, {this.isRecursive: false});
Continuation.retrn() Continuation.retrn()
: parameters = <Parameter>[new Parameter(null)], : parameters = <Parameter>[new Parameter(null)],
isRecursive = false; isRecursive = false;
@ -1001,7 +1012,10 @@ class ReifyRuntimeType extends Primitive {
/// Reference to the internal representation of a type (as produced, for /// Reference to the internal representation of a type (as produced, for
/// example, by [ReadTypeVariable]). /// example, by [ReadTypeVariable]).
final Reference<Primitive> value; final Reference<Primitive> value;
ReifyRuntimeType(Primitive value)
final SourceInformation sourceInformation;
ReifyRuntimeType(Primitive value, this.sourceInformation)
: this.value = new Reference<Primitive>(value); : this.value = new Reference<Primitive>(value);
@override @override
@ -1019,8 +1033,9 @@ class ReifyRuntimeType extends Primitive {
class ReadTypeVariable extends Primitive { class ReadTypeVariable extends Primitive {
final TypeVariableType variable; final TypeVariableType variable;
final Reference<Primitive> target; final Reference<Primitive> target;
final SourceInformation sourceInformation;
ReadTypeVariable(this.variable, Primitive target) ReadTypeVariable(this.variable, Primitive target, this.sourceInformation)
: this.target = new Reference<Primitive>(target); : this.target = new Reference<Primitive>(target);
@override @override

View file

@ -93,3 +93,52 @@ _reportHere(Compiler compiler, Spannable node, String debugMessage) {
compiler.reportInfo(node, compiler.reportInfo(node,
MessageKind.GENERIC, {'text': 'HERE: $debugMessage'}); MessageKind.GENERIC, {'text': 'HERE: $debugMessage'});
} }
/// Set of tracked objects used by [track] and [ifTracked].
var _trackedObjects = new Set();
/// Global default value for the `printTrace` option of [track] and [ifTracked].
bool trackWithTrace = false;
/// If [doTrack] is `true`, add [object] to the set of tracked objects.
///
/// If tracked, [message] is printed along the hash code and toString of
/// [object]. If [printTrace] is `true` a trace printed additionally.
/// If [printTrace] is `null`, [trackWithTrace] determines whether a trace is
/// printed.
///
/// [object] is returned as the result of the method.
track(bool doTrack, Object object, String message, {bool printTrace}) {
if (!doTrack) return object;
_trackedObjects.add(object);
String msg = 'track: ${object.hashCode}:$object:$message';
if (printTrace == null) printTrace = trackWithTrace;
if (printTrace) {
trace(msg);
} else {
debugPrint(msg);
}
return object;
}
/// Returns `true` if [object] is in the set of tracked objects.
///
/// If [message] is provided it is printed along the hash code and toString of
/// [object]. If [printTrace] is `true` a trace printed additionally. If
/// [printTrace] is `null`, [trackWithTrace] determines whether a trace is
/// printed.
bool ifTracked(Object object, {String message, bool printTrace}) {
if (_trackedObjects.contains(object)) {
if (message != null) {
String msg = 'tracked: ${object.hashCode}:$object:$message';
if (printTrace == null) printTrace = trackWithTrace;
if (printTrace) {
trace(msg);
} else {
debugPrint(msg);
}
}
return true;
}
return false;
}

View file

@ -148,6 +148,9 @@ class PositionSourceInformationBuilder implements SourceInformationBuilder {
@override @override
SourceInformation buildGeneric(Node node) => buildBegin(node); SourceInformation buildGeneric(Node node) => buildBegin(node);
@override
SourceInformation buildCreate(Node node) => buildBegin(node);
@override @override
SourceInformation buildReturn(Node node) => buildBegin(node); SourceInformation buildReturn(Node node) => buildBegin(node);

View file

@ -61,6 +61,10 @@ class SourceInformationBuilder {
@deprecated @deprecated
SourceInformation buildGeneric(Node node) => null; SourceInformation buildGeneric(Node node) => null;
/// Generate [SourceInformation] for an instantiation of a class using [node]
/// for the source position.
SourceInformation buildCreate(Node node) => null;
/// Generate [SourceInformation] for the return [node]. /// Generate [SourceInformation] for the return [node].
SourceInformation buildReturn(Node node) => null; SourceInformation buildReturn(Node node) => null;

View file

@ -203,9 +203,10 @@ class StartEndSourceInformationBuilder extends SourceInformationBuilder {
} }
@override @override
SourceInformation buildReturn(Node node) { SourceInformation buildCreate(Node node) => buildGeneric(node);
return buildGeneric(node);
} @override
SourceInformation buildReturn(Node node) => buildGeneric(node);
@override @override
SourceInformation buildGet(Node node) => buildGeneric(node); SourceInformation buildGet(Node node) => buildGeneric(node);

View file

@ -51,7 +51,7 @@ class CodeGenerator extends tree_ir.StatementVisitor
/// Stacks whose top element is the current target of an unlabeled break /// Stacks whose top element is the current target of an unlabeled break
/// or continue. For continues, this is the loop node itself. /// or continue. For continues, this is the loop node itself.
final tree_ir.FallthroughStack shortBreak = new tree_ir.FallthroughStack(); final tree_ir.FallthroughStack shortBreak = new tree_ir.FallthroughStack();
final tree_ir.FallthroughStack shortContinue = final tree_ir.FallthroughStack shortContinue =
new tree_ir.FallthroughStack(); new tree_ir.FallthroughStack();
Set<tree_ir.Label> usedLabels = new Set<tree_ir.Label>(); Set<tree_ir.Label> usedLabels = new Set<tree_ir.Label>();
@ -183,14 +183,18 @@ class CodeGenerator extends tree_ir.StatementVisitor
visitExpression(node.elseExpression)); visitExpression(node.elseExpression));
} }
js.Expression buildConstant(ConstantValue constant) { js.Expression buildConstant(ConstantValue constant,
{SourceInformation sourceInformation}) {
registry.registerCompileTimeConstant(constant); registry.registerCompileTimeConstant(constant);
return glue.constantReference(constant); return glue.constantReference(constant)
.withSourceInformation(sourceInformation);
} }
@override @override
js.Expression visitConstant(tree_ir.Constant node) { js.Expression visitConstant(tree_ir.Constant node) {
return buildConstant(node.value); return buildConstant(
node.value,
sourceInformation: node.sourceInformation);
} }
js.Expression compileConstant(ParameterElement parameter) { js.Expression compileConstant(ParameterElement parameter) {
@ -213,7 +217,8 @@ class CodeGenerator extends tree_ir.StatementVisitor
registry.registerInstantiatedType(node.type); registry.registerInstantiatedType(node.type);
FunctionElement target = node.target; FunctionElement target = node.target;
List<js.Expression> arguments = visitExpressionList(node.arguments); List<js.Expression> arguments = visitExpressionList(node.arguments);
return buildStaticInvoke(target, arguments); return buildStaticInvoke(
target, arguments, sourceInformation: node.sourceInformation);
} }
void registerMethodInvoke(tree_ir.InvokeMethod node) { void registerMethodInvoke(tree_ir.InvokeMethod node) {
@ -240,7 +245,8 @@ class CodeGenerator extends tree_ir.StatementVisitor
registerMethodInvoke(node); registerMethodInvoke(node);
return js.propertyCall(visitExpression(node.receiver), return js.propertyCall(visitExpression(node.receiver),
glue.invocationName(node.selector), glue.invocationName(node.selector),
visitExpressionList(node.arguments)); visitExpressionList(node.arguments))
.withSourceInformation(node.sourceInformation);
} }
@override @override
@ -260,13 +266,15 @@ class CodeGenerator extends tree_ir.StatementVisitor
return js.js('#.#(#)', return js.js('#.#(#)',
[visitExpression(node.receiver), [visitExpression(node.receiver),
glue.instanceMethodName(node.target), glue.instanceMethodName(node.target),
visitExpressionList(node.arguments)]); visitExpressionList(node.arguments)])
.withSourceInformation(node.sourceInformation);
} }
return js.js('#.#.call(#, #)', return js.js('#.#.call(#, #)',
[glue.prototypeAccess(node.target.enclosingClass), [glue.prototypeAccess(node.target.enclosingClass),
glue.invocationName(node.selector), glue.invocationName(node.selector),
visitExpression(node.receiver), visitExpression(node.receiver),
visitExpressionList(node.arguments)]); visitExpressionList(node.arguments)])
.withSourceInformation(node.sourceInformation);
} }
@override @override
@ -425,7 +433,7 @@ class CodeGenerator extends tree_ir.StatementVisitor
} else if (isEffectiveBreakTarget(node, shortBreak.target)) { } else if (isEffectiveBreakTarget(node, shortBreak.target)) {
// Unlabeled break to the break target or to an equivalent break. // Unlabeled break to the break target or to an equivalent break.
shortBreak.use(); shortBreak.use();
accumulator.add(new js.Break(null)); accumulator.add(new js.Break(null));
} else { } else {
usedLabels.add(node.target); usedLabels.add(node.target);
accumulator.add(new js.Break(node.target.name)); accumulator.add(new js.Break(node.target.name));
@ -547,7 +555,8 @@ class CodeGenerator extends tree_ir.StatementVisitor
registry.registerCompileTimeConstant(new NullConstantValue()); registry.registerCompileTimeConstant(new NullConstantValue());
fallthrough.use(); fallthrough.use();
} else { } else {
accumulator.add(new js.Return(visitExpression(node.value))); accumulator.add(new js.Return(visitExpression(node.value))
.withSourceInformation(node.sourceInformation));
} }
} }
@ -596,7 +605,8 @@ class CodeGenerator extends tree_ir.StatementVisitor
} }
js.Expression instance = new js.New( js.Expression instance = new js.New(
glue.constructorAccess(classElement), glue.constructorAccess(classElement),
visitExpressionList(node.arguments)); visitExpressionList(node.arguments))
.withSourceInformation(node.sourceInformation);
List<tree_ir.Expression> typeInformation = node.typeInformation; List<tree_ir.Expression> typeInformation = node.typeInformation;
assert(typeInformation.isEmpty || assert(typeInformation.isEmpty ||
@ -606,7 +616,8 @@ class CodeGenerator extends tree_ir.StatementVisitor
js.Expression typeArguments = new js.ArrayInitializer( js.Expression typeArguments = new js.ArrayInitializer(
visitExpressionList(typeInformation)); visitExpressionList(typeInformation));
return buildStaticHelperInvocation(helper, return buildStaticHelperInvocation(helper,
<js.Expression>[instance, typeArguments]); <js.Expression>[instance, typeArguments],
sourceInformation: node.sourceInformation);
} else { } else {
return instance; return instance;
} }
@ -704,19 +715,25 @@ class CodeGenerator extends tree_ir.StatementVisitor
visitExpression(node.value)]); visitExpression(node.value)]);
} }
js.Expression buildStaticHelperInvocation(FunctionElement helper, js.Expression buildStaticHelperInvocation(
List<js.Expression> arguments) { FunctionElement helper,
List<js.Expression> arguments,
{SourceInformation sourceInformation}) {
registry.registerStaticUse(helper); registry.registerStaticUse(helper);
return buildStaticInvoke(helper, arguments); return buildStaticInvoke(
helper, arguments, sourceInformation: sourceInformation);
} }
@override @override
js.Expression visitReifyRuntimeType(tree_ir.ReifyRuntimeType node) { js.Expression visitReifyRuntimeType(tree_ir.ReifyRuntimeType node) {
FunctionElement createType = glue.getCreateRuntimeType(); js.Expression typeToString = buildStaticHelperInvocation(
FunctionElement typeToString = glue.getRuntimeTypeToString(); glue.getRuntimeTypeToString(),
return buildStaticHelperInvocation(createType, [visitExpression(node.value)],
[buildStaticHelperInvocation(typeToString, sourceInformation: node.sourceInformation);
[visitExpression(node.value)])]); return buildStaticHelperInvocation(
glue.getCreateRuntimeType(),
[typeToString],
sourceInformation: node.sourceInformation);
} }
@override @override
@ -727,11 +744,13 @@ class CodeGenerator extends tree_ir.StatementVisitor
js.Expression typeName = glue.getRuntimeTypeName(context); js.Expression typeName = glue.getRuntimeTypeName(context);
return buildStaticHelperInvocation( return buildStaticHelperInvocation(
glue.getRuntimeTypeArgument(), glue.getRuntimeTypeArgument(),
[visitExpression(node.target), typeName, index]); [visitExpression(node.target), typeName, index],
sourceInformation: node.sourceInformation);
} else { } else {
return buildStaticHelperInvocation( return buildStaticHelperInvocation(
glue.getTypeArgumentByIndex(), glue.getTypeArgumentByIndex(),
[visitExpression(node.target), index]); [visitExpression(node.target), index],
sourceInformation: node.sourceInformation);
} }
} }

View file

@ -2191,8 +2191,10 @@ class SsaBuilder extends ast.Visitor
constructorArguments, constructorArguments,
instantiatedTypes); instantiatedTypes);
if (function != null) { if (function != null) {
// TODO(johnniwinther): Provide source information for creation
// through synthetic constructors.
newObject.sourceInformation = newObject.sourceInformation =
sourceInformationBuilder.buildGeneric(function); sourceInformationBuilder.buildCreate(function);
} }
add(newObject); add(newObject);
} else { } else {
@ -3147,7 +3149,7 @@ class SsaBuilder extends ast.Visitor
TypeMask type = TypeMask type =
new TypeMask.nonNullExact(compiler.functionClass, compiler.world); new TypeMask.nonNullExact(compiler.functionClass, compiler.world);
push(new HForeignNew(closureClassElement, type, capturedVariables) push(new HForeignNew(closureClassElement, type, capturedVariables)
..sourceInformation = sourceInformationBuilder.buildGeneric(node)); ..sourceInformation = sourceInformationBuilder.buildCreate(node));
Element methodElement = nestedClosureData.closureElement; Element methodElement = nestedClosureData.closureElement;
registry.registerInstantiatedClosure(methodElement); registry.registerInstantiatedClosure(methodElement);

View file

@ -6,6 +6,7 @@ library tree_ir.optimization.statement_rewriter;
import 'optimization.dart' show Pass; import 'optimization.dart' show Pass;
import '../tree_ir_nodes.dart'; import '../tree_ir_nodes.dart';
import '../../io/source_information.dart';
/** /**
* Translates to direct-style. * Translates to direct-style.
@ -924,7 +925,11 @@ class StatementRewriter extends Transformer implements Pass {
if (s is Return && t is Return) { if (s is Return && t is Return) {
CombinedExpressions values = combineExpressions(s.value, t.value); CombinedExpressions values = combineExpressions(s.value, t.value);
if (values != null) { if (values != null) {
return new Return(values.combined); // TODO(johnniwinther): Handle multiple source informations.
SourceInformation sourceInformation = s.sourceInformation != null
? s.sourceInformation : t.sourceInformation;
return new Return(values.combined,
sourceInformation: sourceInformation);
} }
} }
if (s is ExpressionStatement && t is ExpressionStatement) { if (s is ExpressionStatement && t is ExpressionStatement) {

View file

@ -274,7 +274,8 @@ class Builder implements cps_ir.Visitor<Node> {
return new CreateInstance( return new CreateInstance(
node.classElement, node.classElement,
translateArguments(node.arguments), translateArguments(node.arguments),
translateArguments(node.typeInformation)); translateArguments(node.typeInformation),
node.sourceInformation);
} }
Expression visitGetField(cps_ir.GetField node) { Expression visitGetField(cps_ir.GetField node) {
@ -355,10 +356,12 @@ class Builder implements cps_ir.Visitor<Node> {
} }
Statement visitInvokeMethod(cps_ir.InvokeMethod node) { Statement visitInvokeMethod(cps_ir.InvokeMethod node) {
InvokeMethod invoke = new InvokeMethod(getVariableUse(node.receiver), InvokeMethod invoke = new InvokeMethod(
node.selector, getVariableUse(node.receiver),
node.mask, node.selector,
translateArguments(node.arguments)); node.mask,
translateArguments(node.arguments),
node.sourceInformation);
invoke.receiverIsNotNull = node.receiverIsNotNull; invoke.receiverIsNotNull = node.receiverIsNotNull;
return continueWithExpression(node.continuation, invoke); return continueWithExpression(node.continuation, invoke);
} }
@ -367,7 +370,7 @@ class Builder implements cps_ir.Visitor<Node> {
Expression receiver = getVariableUse(node.receiver); Expression receiver = getVariableUse(node.receiver);
List<Expression> arguments = translateArguments(node.arguments); List<Expression> arguments = translateArguments(node.arguments);
Expression invoke = new InvokeMethodDirectly(receiver, node.target, Expression invoke = new InvokeMethodDirectly(receiver, node.target,
node.selector, arguments); node.selector, arguments, node.sourceInformation);
return continueWithExpression(node.continuation, invoke); return continueWithExpression(node.continuation, invoke);
} }
@ -439,7 +442,8 @@ class Builder implements cps_ir.Visitor<Node> {
node.type, node.type,
node.target, node.target,
node.selector, node.selector,
arguments); arguments,
node.sourceInformation);
return continueWithExpression(node.continuation, invoke); return continueWithExpression(node.continuation, invoke);
} }
@ -452,7 +456,8 @@ class Builder implements cps_ir.Visitor<Node> {
cps_ir.Continuation cont = node.continuation.definition; cps_ir.Continuation cont = node.continuation.definition;
if (cont == returnContinuation) { if (cont == returnContinuation) {
assert(node.arguments.length == 1); assert(node.arguments.length == 1);
return new Return(getVariableUse(node.arguments.single)); return new Return(getVariableUse(node.arguments.single),
sourceInformation: node.sourceInformation);
} else { } else {
List<Expression> arguments = translateArguments(node.arguments); List<Expression> arguments = translateArguments(node.arguments);
return buildPhiAssignments(cont.parameters, arguments, return buildPhiAssignments(cont.parameters, arguments,
@ -500,7 +505,7 @@ class Builder implements cps_ir.Visitor<Node> {
} }
Expression visitConstant(cps_ir.Constant node) { Expression visitConstant(cps_ir.Constant node) {
return new Constant(node.value); return new Constant(node.value, sourceInformation: node.sourceInformation);
} }
Expression visitLiteralList(cps_ir.LiteralList node) { Expression visitLiteralList(cps_ir.LiteralList node) {
@ -552,11 +557,15 @@ class Builder implements cps_ir.Visitor<Node> {
} }
Expression visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) { Expression visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
return new ReifyRuntimeType(getVariableUse(node.value)); return new ReifyRuntimeType(
getVariableUse(node.value), node.sourceInformation);
} }
Expression visitReadTypeVariable(cps_ir.ReadTypeVariable node) { Expression visitReadTypeVariable(cps_ir.ReadTypeVariable node) {
return new ReadTypeVariable(node.variable, getVariableUse(node.target)); return new ReadTypeVariable(
node.variable,
getVariableUse(node.target),
node.sourceInformation);
} }
@override @override

View file

@ -201,11 +201,16 @@ class InvokeMethod extends Expression implements Invoke {
final Selector selector; final Selector selector;
final TypeMask mask; final TypeMask mask;
final List<Expression> arguments; final List<Expression> arguments;
final SourceInformation sourceInformation;
/// If true, it is known that the receiver cannot be `null`. /// If true, it is known that the receiver cannot be `null`.
bool receiverIsNotNull = false; bool receiverIsNotNull = false;
InvokeMethod(this.receiver, this.selector, this.mask, this.arguments) { InvokeMethod(this.receiver,
this.selector,
this.mask,
this.arguments,
this.sourceInformation) {
assert(receiver != null); assert(receiver != null);
} }
@ -224,9 +229,10 @@ class InvokeMethodDirectly extends Expression implements Invoke {
final Element target; final Element target;
final Selector selector; final Selector selector;
final List<Expression> arguments; final List<Expression> arguments;
final SourceInformation sourceInformation;
InvokeMethodDirectly(this.receiver, this.target, this.selector, InvokeMethodDirectly(this.receiver, this.target, this.selector,
this.arguments); this.arguments, this.sourceInformation);
accept(ExpressionVisitor visitor) => visitor.visitInvokeMethodDirectly(this); accept(ExpressionVisitor visitor) => visitor.visitInvokeMethodDirectly(this);
accept1(ExpressionVisitor1 visitor, arg) { accept1(ExpressionVisitor1 visitor, arg) {
@ -242,12 +248,13 @@ class InvokeConstructor extends Expression implements Invoke {
final FunctionElement target; final FunctionElement target;
final List<Expression> arguments; final List<Expression> arguments;
final Selector selector; final Selector selector;
final SourceInformation sourceInformation;
/// TODO(karlklose): get rid of this field. Instead use the constant's /// TODO(karlklose): get rid of this field. Instead use the constant's
/// expression to find the constructor to be called in dart2dart. /// expression to find the constructor to be called in dart2dart.
final values.ConstantValue constant; final values.ConstantValue constant;
InvokeConstructor(this.type, this.target, this.selector, this.arguments, InvokeConstructor(this.type, this.target, this.selector, this.arguments,
[this.constant]); this.sourceInformation, [this.constant]);
ClassElement get targetClass => target.enclosingElement; ClassElement get targetClass => target.enclosingElement;
@ -265,14 +272,18 @@ class InvokeConstructor extends Expression implements Invoke {
*/ */
class Constant extends Expression { class Constant extends Expression {
final values.ConstantValue value; final values.ConstantValue value;
final SourceInformation sourceInformation;
Constant(this.value); Constant(this.value, {this.sourceInformation});
Constant.bool(values.BoolConstantValue constantValue) Constant.bool(values.BoolConstantValue constantValue)
: value = constantValue; : value = constantValue,
sourceInformation = null;
accept(ExpressionVisitor visitor) => visitor.visitConstant(this); accept(ExpressionVisitor visitor) => visitor.visitConstant(this);
accept1(ExpressionVisitor1 visitor, arg) => visitor.visitConstant(this, arg); accept1(ExpressionVisitor1 visitor, arg) => visitor.visitConstant(this, arg);
String toString() => 'Constant(value=${value.toStructuredString()})';
} }
class This extends Expression { class This extends Expression {
@ -364,6 +375,9 @@ class Conditional extends Expression {
accept1(ExpressionVisitor1 visitor, arg) { accept1(ExpressionVisitor1 visitor, arg) {
return visitor.visitConditional(this, arg); return visitor.visitConditional(this, arg);
} }
String toString() => 'Conditional(condition=$condition,thenExpression='
'$thenExpression,elseExpression=$elseExpression)';
} }
/// An && or || expression. The operator is internally represented as a boolean /// An && or || expression. The operator is internally represented as a boolean
@ -383,6 +397,8 @@ class LogicalOperator extends Expression {
accept1(ExpressionVisitor1 visitor, arg) { accept1(ExpressionVisitor1 visitor, arg) {
return visitor.visitLogicalOperator(this, arg); return visitor.visitLogicalOperator(this, arg);
} }
String toString() => 'LogicalOperator(left=$left,right=$right,isAnd=$isAnd)';
} }
/// Logical negation. /// Logical negation.
@ -541,11 +557,12 @@ class Return extends Statement {
/// Even in constructors this holds true. Take special care when translating /// Even in constructors this holds true. Take special care when translating
/// back to dart, where `return null;` in a constructor is an error. /// back to dart, where `return null;` in a constructor is an error.
Expression value; Expression value;
SourceInformation sourceInformation;
Statement get next => null; Statement get next => null;
void set next(Statement s) => throw 'UNREACHABLE'; void set next(Statement s) => throw 'UNREACHABLE';
Return(this.value); Return(this.value, {this.sourceInformation});
accept(StatementVisitor visitor) => visitor.visitReturn(this); accept(StatementVisitor visitor) => visitor.visitReturn(this);
accept1(StatementVisitor1 visitor, arg) => visitor.visitReturn(this, arg); accept1(StatementVisitor1 visitor, arg) => visitor.visitReturn(this, arg);
@ -664,8 +681,10 @@ class CreateInstance extends Expression {
ClassElement classElement; ClassElement classElement;
List<Expression> arguments; List<Expression> arguments;
List<Expression> typeInformation; List<Expression> typeInformation;
SourceInformation sourceInformation;
CreateInstance(this.classElement, this.arguments, this.typeInformation); CreateInstance(this.classElement, this.arguments,
this.typeInformation, this.sourceInformation);
accept(ExpressionVisitor visitor) => visitor.visitCreateInstance(this); accept(ExpressionVisitor visitor) => visitor.visitCreateInstance(this);
accept1(ExpressionVisitor1 visitor, arg) { accept1(ExpressionVisitor1 visitor, arg) {
@ -749,8 +768,9 @@ class SetIndex extends Expression {
class ReifyRuntimeType extends Expression { class ReifyRuntimeType extends Expression {
Expression value; Expression value;
SourceInformation sourceInformation;
ReifyRuntimeType(this.value); ReifyRuntimeType(this.value, this.sourceInformation);
accept(ExpressionVisitor visitor) { accept(ExpressionVisitor visitor) {
return visitor.visitReifyRuntimeType(this); return visitor.visitReifyRuntimeType(this);
@ -764,8 +784,9 @@ class ReifyRuntimeType extends Expression {
class ReadTypeVariable extends Expression { class ReadTypeVariable extends Expression {
final TypeVariableType variable; final TypeVariableType variable;
Expression target; Expression target;
final SourceInformation sourceInformation;
ReadTypeVariable(this.variable, this.target); ReadTypeVariable(this.variable, this.target, this.sourceInformation);
accept(ExpressionVisitor visitor) { accept(ExpressionVisitor visitor) {
return visitor.visitReadTypeVariable(this); return visitor.visitReadTypeVariable(this);

View file

@ -36,6 +36,7 @@ invokes(parameter) {
parameter(); parameter();
localVariable(); localVariable();
localFunction(); localFunction();
(parameter)();
parameter.dynamicInvoke(); parameter.dynamicInvoke();
new C(parameter).instanceInvokes(); new C(parameter).instanceInvokes();

View file

@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a // 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. // BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'package:async_helper/async_helper.dart'; import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart'; import 'package:expect/expect.dart';
import 'sourcemap_helper.dart'; import 'sourcemap_helper.dart';
@ -10,42 +11,134 @@ import 'package:compiler/src/filenames.dart';
main(List<String> arguments) { main(List<String> arguments) {
bool showAll = false; bool showAll = false;
bool measure = false;
Uri outputUri; Uri outputUri;
if (arguments.isNotEmpty) { Set<String> configurations = new Set<String>();
outputUri = Uri.base.resolve(nativeToUriPath(arguments.last)); for (String argument in arguments) {
showAll = arguments.contains('-a'); if (argument.startsWith('-')) {
} if (argument == '-a') {
asyncTest(() async { /// Generate visualization for all user methods.
String filename = showAll = true;
'tests/compiler/dart2js/sourcemaps/invokes_test_file.dart'; } else if (argument == '-m') {
SourceMapProcessor processor = new SourceMapProcessor(filename); /// Measure instead of reporting the number of missing code points.
List<SourceMapInfo> infoList = await processor.process( measure = true;
['--use-new-source-info', '--csp', '--disable-inlining']); } else if (argument.startsWith('--out=')) {
List<SourceMapInfo> userInfoList = <SourceMapInfo>[]; /// Generate visualization for the first configuration.
List<SourceMapInfo> failureList = <SourceMapInfo>[]; outputUri = Uri.base.resolve(
for (SourceMapInfo info in infoList) { nativeToUriPath(argument.substring('--out='.length)));
if (info.element.library.isPlatformLibrary) continue; } else if (argument.startsWith('-o')) {
userInfoList.add(info); /// Generate visualization for the first configuration.
Iterable<CodePoint> missingCodePoints = outputUri = Uri.base.resolve(
info.codePoints.where((c) => c.isMissing); nativeToUriPath(argument.substring('-o'.length)));
if (!missingCodePoints.isEmpty) { } else {
print('Missing code points ${missingCodePoints} for ' print("Unknown option '$argument'.");
'${info.element} in $filename'); return;
failureList.add(info); }
} else {
if (TEST_CONFIGURATIONS.containsKey(argument)) {
configurations.add(argument);
} else {
print("Unknown configuration '$argument'. "
"Must be one of '${TEST_CONFIGURATIONS.keys.join("', '")}'");
return;
} }
} }
if (failureList.isNotEmpty) { }
if (outputUri == null) {
Expect.fail( if (configurations.isEmpty) {
"Missing code points found. " configurations.addAll(TEST_CONFIGURATIONS.keys);
"Run the test with a URI option, `source_mapping_test <uri>`, to " }
"create a html visualization of the missing code points."); String outputConfig = configurations.first;
} else {
createTraceSourceMapHtml(outputUri, processor, asyncTest(() async {
showAll ? userInfoList : failureList); List<Measurement> measurements = <Measurement>[];
for (String config in configurations) {
List<String> options = TEST_CONFIGURATIONS[config];
Measurement measurement = await runTests(
config,
options,
showAll: showAll,
measure: measure,
outputUri: outputConfig == config ? outputUri : null);
if (measurement != null) {
measurements.add(measurement);
} }
} else if (outputUri != null) { }
createTraceSourceMapHtml(outputUri, processor, userInfoList); for (Measurement measurement in measurements) {
print(measurement);
} }
}); });
} }
const Map<String, List<String>> TEST_CONFIGURATIONS = const {
'old': const [],
'ssa': const ['--use-new-source-info', ],
'cps': const ['--use-new-source-info', '--use-cps-ir'],
};
Future<Measurement> runTests(
String config,
List<String> options,
{bool showAll: false,
Uri outputUri,
bool measure: false}) async {
if (config == 'old' && !measure) return null;
String filename =
'tests/compiler/dart2js/sourcemaps/invokes_test_file.dart';
SourceMapProcessor processor = new SourceMapProcessor(filename);
List<SourceMapInfo> infoList = await processor.process(
['--csp', '--disable-inlining']
..addAll(options),
verbose: !measure);
List<SourceMapInfo> userInfoList = <SourceMapInfo>[];
List<SourceMapInfo> failureList = <SourceMapInfo>[];
Measurement measurement = new Measurement(config);
for (SourceMapInfo info in infoList) {
if (info.element.library.isPlatformLibrary) continue;
userInfoList.add(info);
Iterable<CodePoint> missingCodePoints =
info.codePoints.where((c) => c.isMissing);
measurement.missing += missingCodePoints.length;
measurement.count += info.codePoints.length;
if (!measure) {
if (!missingCodePoints.isEmpty) {
print("Missing code points for ${info.element} in '$filename':");
for (CodePoint codePoint in missingCodePoints) {
print(" $codePoint");
}
failureList.add(info);
}
}
}
if (failureList.isNotEmpty) {
if (outputUri == null) {
if (!measure) {
Expect.fail(
"Missing code points found. "
"Run the test with a URI option, "
"`source_mapping_test --out=<uri> $config`, to "
"create a html visualization of the missing code points.");
}
} else {
createTraceSourceMapHtml(outputUri, processor,
showAll ? userInfoList : failureList);
}
} else if (outputUri != null) {
createTraceSourceMapHtml(outputUri, processor, userInfoList);
}
return measurement;
}
class Measurement {
final String config;
int missing = 0;
int count = 0;
Measurement(this.config);
String toString() {
double percentage = 100 * missing / count;
return "Config '${config}': $missing of $count ($percentage%) missing";
}
}

View file

@ -7,7 +7,8 @@ library sourcemap.helper;
import 'dart:async'; import 'dart:async';
import 'package:compiler/src/apiimpl.dart' as api; import 'package:compiler/src/apiimpl.dart' as api;
import 'package:compiler/src/dart2jslib.dart' show NullSink; import 'package:compiler/src/dart2jslib.dart' show NullSink;
import "package:compiler/src/elements/elements.dart"; import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/helpers/helpers.dart';
import 'package:compiler/src/filenames.dart'; import 'package:compiler/src/filenames.dart';
import 'package:compiler/src/io/source_file.dart'; import 'package:compiler/src/io/source_file.dart';
import 'package:compiler/src/io/source_information.dart'; import 'package:compiler/src/io/source_information.dart';
@ -106,20 +107,23 @@ class SourceMapProcessor {
} }
/// Computes the [SourceMapInfo] for the compiled elements. /// Computes the [SourceMapInfo] for the compiled elements.
Future<List<SourceMapInfo>> process(List<String> options) async { Future<List<SourceMapInfo>> process(
List<String> options,
{bool verbose: true}) async {
OutputProvider outputProvider = outputToFile OutputProvider outputProvider = outputToFile
? new OutputProvider() ? new OutputProvider()
: new CloningOutputProvider(targetUri, sourceMapFileUri); : new CloningOutputProvider(targetUri, sourceMapFileUri);
if (options.contains('--use-new-source-info')) { if (options.contains('--use-new-source-info')) {
print('Using the new source information system.'); if (verbose) print('Using the new source information system.');
useNewSourceInfo = true; useNewSourceInfo = true;
} }
api.Compiler compiler = await compilerFor({}, api.Compiler compiler = await compilerFor({},
outputProvider: outputProvider, outputProvider: outputProvider,
// TODO(johnniwinther): Use [verbose] to avoid showing diagnostics.
options: ['--out=$targetUri', '--source-map=$sourceMapFileUri'] options: ['--out=$targetUri', '--source-map=$sourceMapFileUri']
..addAll(options)); ..addAll(options));
if (options.contains('--disable-inlining')) { if (options.contains('--disable-inlining')) {
print('Inlining disabled'); if (verbose) print('Inlining disabled');
compiler.disableInlining = true; compiler.disableInlining = true;
} }