mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 13:08:01 +00:00
Add source information to parameter stubs.
Change-Id: If942cc13203752361c3104c89190d75979073498 Reviewed-on: https://dart-review.googlesource.com/34440 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
parent
33952ad8f6
commit
d539c78af1
|
@ -667,6 +667,8 @@ class SynthesizedCallMethodElementX extends BaseFunctionElementX
|
|||
return closureClass.methodElement.memberContext;
|
||||
}
|
||||
|
||||
SourceSpan get sourcePosition => expression.sourcePosition;
|
||||
|
||||
bool get hasNode => node != null;
|
||||
|
||||
FunctionExpression parseNode(ParsingContext parsing) => node;
|
||||
|
|
|
@ -11,6 +11,7 @@ import 'package:kernel/ast.dart' as ir;
|
|||
import '../elements/entities.dart';
|
||||
import '../kernel/element_map.dart';
|
||||
import '../js_model/js_strategy.dart';
|
||||
import '../universe/call_structure.dart';
|
||||
import 'source_information.dart';
|
||||
import 'position_information.dart';
|
||||
|
||||
|
@ -28,13 +29,15 @@ class KernelSourceInformationStrategy
|
|||
}
|
||||
}
|
||||
|
||||
/// Compute the source map name for kernel based [member].
|
||||
/// Compute the source map name for kernel based [member]. If [callStructure]
|
||||
/// is non-null it is used to name the parameter stub for [element].
|
||||
///
|
||||
/// [elementMap] is used to compute names for closure call methods.
|
||||
// TODO(johnniwinther): Make the closure call names available to
|
||||
// `sourcemap_helper.dart`.
|
||||
String computeKernelElementNameForSourceMaps(
|
||||
KernelToElementMapForBuilding elementMap, MemberEntity member) {
|
||||
KernelToElementMapForBuilding elementMap, MemberEntity member,
|
||||
[CallStructure callStructure]) {
|
||||
MemberDefinition definition = elementMap.getMemberDefinition(member);
|
||||
switch (definition.kind) {
|
||||
case MemberKind.closureCall:
|
||||
|
@ -58,10 +61,10 @@ String computeKernelElementNameForSourceMaps(
|
|||
}
|
||||
MemberEntity enclosingMember = elementMap.getMember(node);
|
||||
String enclosingMemberName =
|
||||
computeElementNameForSourceMaps(enclosingMember);
|
||||
computeElementNameForSourceMaps(enclosingMember, callStructure);
|
||||
return '$enclosingMemberName.$name';
|
||||
default:
|
||||
return computeElementNameForSourceMaps(member);
|
||||
return computeElementNameForSourceMaps(member, callStructure);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,11 +80,13 @@ class KernelSourceInformationBuilder
|
|||
: this._name =
|
||||
computeKernelElementNameForSourceMaps(_elementMap, _member);
|
||||
|
||||
/// Returns the [SourceLocation] for the [offset] within [node].
|
||||
/// Returns the [SourceLocation] for the [offset] within [node] using [name]
|
||||
/// as the name of the source location.
|
||||
///
|
||||
/// If [offset] is `null`, the first `fileOffset` of [node] or its parents is
|
||||
/// used.
|
||||
SourceLocation _getSourceLocation(ir.TreeNode node, [int offset]) {
|
||||
SourceLocation _getSourceLocation(String name, ir.TreeNode node,
|
||||
[int offset]) {
|
||||
ir.Location location;
|
||||
if (offset != null) {
|
||||
location = node.location;
|
||||
|
@ -93,7 +98,7 @@ class KernelSourceInformationBuilder
|
|||
location = node.location;
|
||||
offset = node.fileOffset;
|
||||
}
|
||||
return new KernelSourceLocation(location, offset, _name);
|
||||
return new KernelSourceLocation(location, offset, name);
|
||||
}
|
||||
|
||||
/// Creates the source information for a function definition defined by the
|
||||
|
@ -101,10 +106,10 @@ class KernelSourceInformationBuilder
|
|||
///
|
||||
/// This method handles both methods, constructors, and local functions.
|
||||
SourceInformation _buildFunction(
|
||||
ir.TreeNode node, ir.FunctionNode functionNode) {
|
||||
String name, ir.TreeNode node, ir.FunctionNode functionNode) {
|
||||
if (functionNode.fileEndOffset != ir.TreeNode.noOffset) {
|
||||
return new PositionSourceInformation(_getSourceLocation(node),
|
||||
_getSourceLocation(functionNode, functionNode.fileEndOffset));
|
||||
return new PositionSourceInformation(_getSourceLocation(name, node),
|
||||
_getSourceLocation(name, functionNode, functionNode.fileEndOffset));
|
||||
}
|
||||
return _buildTreeNode(node);
|
||||
}
|
||||
|
@ -116,31 +121,32 @@ class KernelSourceInformationBuilder
|
|||
/// to the end of the member as the closing position.
|
||||
SourceInformation _buildFunctionEnd(MemberEntity member, [ir.TreeNode base]) {
|
||||
MemberDefinition definition = _elementMap.getMemberDefinition(member);
|
||||
String name = computeKernelElementNameForSourceMaps(_elementMap, member);
|
||||
ir.Node node = definition.node;
|
||||
switch (definition.kind) {
|
||||
case MemberKind.regular:
|
||||
if (node is ir.Procedure) {
|
||||
return _buildFunction(base ?? node, node.function);
|
||||
return _buildFunction(name, base ?? node, node.function);
|
||||
}
|
||||
break;
|
||||
case MemberKind.constructor:
|
||||
case MemberKind.constructorBody:
|
||||
if (node is ir.Procedure) {
|
||||
return _buildFunction(base ?? node, node.function);
|
||||
return _buildFunction(name, base ?? node, node.function);
|
||||
} else if (node is ir.Constructor) {
|
||||
return _buildFunction(base ?? node, node.function);
|
||||
return _buildFunction(name, base ?? node, node.function);
|
||||
}
|
||||
break;
|
||||
case MemberKind.closureCall:
|
||||
if (node is ir.FunctionDeclaration) {
|
||||
return _buildFunction(base ?? node, node.function);
|
||||
return _buildFunction(name, base ?? node, node.function);
|
||||
} else if (node is ir.FunctionExpression) {
|
||||
return _buildFunction(base ?? node, node.function);
|
||||
return _buildFunction(name, base ?? node, node.function);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
return _buildTreeNode(base ?? node);
|
||||
return _buildTreeNode(base ?? node, name: name);
|
||||
}
|
||||
|
||||
/// Creates the source information for exiting a function definition defined
|
||||
|
@ -151,7 +157,7 @@ class KernelSourceInformationBuilder
|
|||
ir.TreeNode node, ir.FunctionNode functionNode) {
|
||||
if (functionNode.fileEndOffset != ir.TreeNode.noOffset) {
|
||||
return new PositionSourceInformation(
|
||||
_getSourceLocation(functionNode, functionNode.fileEndOffset));
|
||||
_getSourceLocation(_name, functionNode, functionNode.fileEndOffset));
|
||||
}
|
||||
return _buildTreeNode(node);
|
||||
}
|
||||
|
@ -164,12 +170,12 @@ class KernelSourceInformationBuilder
|
|||
SourceLocation location;
|
||||
if (body != null) {
|
||||
if (body is ir.Block && body.statements.isNotEmpty) {
|
||||
location = _getSourceLocation(body.statements.first);
|
||||
location = _getSourceLocation(_name, body.statements.first);
|
||||
} else {
|
||||
location = _getSourceLocation(body);
|
||||
location = _getSourceLocation(_name, body);
|
||||
}
|
||||
} else {
|
||||
location = _getSourceLocation(node);
|
||||
location = _getSourceLocation(_name, node);
|
||||
}
|
||||
return new PositionSourceInformation(location);
|
||||
}
|
||||
|
@ -242,9 +248,9 @@ class KernelSourceInformationBuilder
|
|||
|
||||
/// Creates source information based on the location of [node].
|
||||
SourceInformation _buildTreeNode(ir.TreeNode node,
|
||||
[SourceLocation closingPosition]) {
|
||||
{SourceLocation closingPosition, String name}) {
|
||||
return new PositionSourceInformation(
|
||||
_getSourceLocation(node), closingPosition);
|
||||
_getSourceLocation(name ?? _name, node), closingPosition);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -370,7 +376,7 @@ class KernelSourceInformationBuilder
|
|||
SourceInformation buildCall(
|
||||
covariant ir.TreeNode receiver, covariant ir.TreeNode call) {
|
||||
return new PositionSourceInformation(
|
||||
_getSourceLocation(receiver), _getSourceLocation(call));
|
||||
_getSourceLocation(_name, receiver), _getSourceLocation(_name, call));
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -409,6 +415,16 @@ class KernelSourceInformationBuilder
|
|||
return _buildFunctionEnd(member);
|
||||
}
|
||||
|
||||
@override
|
||||
SourceInformation buildStub(
|
||||
FunctionEntity function, CallStructure callStructure) {
|
||||
MemberDefinition definition = _elementMap.getMemberDefinition(function);
|
||||
String name = computeKernelElementNameForSourceMaps(
|
||||
_elementMap, function, callStructure);
|
||||
ir.Node node = definition.node;
|
||||
return _buildTreeNode(node, name: name);
|
||||
}
|
||||
|
||||
@override
|
||||
SourceInformation buildGoto(ir.Node node) {
|
||||
return _buildTreeNode(node);
|
||||
|
|
|
@ -11,6 +11,7 @@ import '../common.dart';
|
|||
import '../elements/entities.dart';
|
||||
import '../js/js_source_mapping.dart';
|
||||
import '../js/js.dart' as js;
|
||||
import '../universe/call_structure.dart';
|
||||
import 'code_output.dart' show BufferedCodeOutput;
|
||||
import 'source_information.dart';
|
||||
|
||||
|
@ -288,6 +289,13 @@ class MultiSourceInformationBuilder<T> implements SourceInformationBuilder<T> {
|
|||
builders.map((b) => b.buildDeclaration(member)).toList());
|
||||
}
|
||||
|
||||
@override
|
||||
SourceInformation buildStub(
|
||||
FunctionEntity function, CallStructure callStructure) {
|
||||
return new MultiSourceInformation(
|
||||
builders.map((b) => b.buildStub(function, callStructure)).toList());
|
||||
}
|
||||
|
||||
@override
|
||||
SourceInformation buildGoto(T node) {
|
||||
return new MultiSourceInformation(
|
||||
|
|
|
@ -9,11 +9,12 @@ library dart2js.source_information.position;
|
|||
|
||||
import '../common.dart';
|
||||
import '../elements/elements.dart'
|
||||
show MemberElement, ResolvedAst, ResolvedAstKind;
|
||||
show MemberElement, MethodElement, ResolvedAst, ResolvedAstKind;
|
||||
import '../js/js.dart' as js;
|
||||
import '../js/js_debug.dart';
|
||||
import '../js/js_source_mapping.dart';
|
||||
import '../tree/tree.dart' show Node, Send;
|
||||
import '../universe/call_structure.dart';
|
||||
import 'code_output.dart' show BufferedCodeOutput;
|
||||
import 'source_file.dart';
|
||||
import 'source_information.dart';
|
||||
|
@ -158,7 +159,8 @@ class PositionSourceInformationBuilder
|
|||
|
||||
SourceInformation buildDeclaration(MemberElement member) {
|
||||
ResolvedAst resolvedAst = member.resolvedAst;
|
||||
SourceFile sourceFile = computeSourceFile(member.resolvedAst);
|
||||
String name = computeElementNameForSourceMaps(resolvedAst.element);
|
||||
SourceFile sourceFile = computeSourceFile(resolvedAst);
|
||||
if (resolvedAst.kind != ResolvedAstKind.PARSED) {
|
||||
SourceSpan span = resolvedAst.element.sourcePosition;
|
||||
return new PositionSourceInformation(
|
||||
|
@ -172,6 +174,20 @@ class PositionSourceInformationBuilder
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
SourceInformation buildStub(
|
||||
MethodElement function, CallStructure callStructure) {
|
||||
ResolvedAst resolvedAst = function.resolvedAst;
|
||||
String name =
|
||||
computeElementNameForSourceMaps(resolvedAst.element, callStructure);
|
||||
SourceFile sourceFile = computeSourceFile(resolvedAst);
|
||||
SourceSpan span = resolvedAst.element.sourcePosition;
|
||||
assert(
|
||||
span != null, failedAt(function, "No source position for $function."));
|
||||
return new PositionSourceInformation(
|
||||
new OffsetSourceLocation(sourceFile, span.begin, name));
|
||||
}
|
||||
|
||||
/// Builds a source information object pointing the start position of [node].
|
||||
SourceInformation buildBegin(Node node) {
|
||||
return new PositionSourceInformation(new OffsetSourceLocation(
|
||||
|
|
|
@ -16,6 +16,7 @@ import '../elements/elements.dart'
|
|||
import '../elements/entities.dart';
|
||||
import '../js/js.dart' show JavaScriptNodeSourceInformation;
|
||||
import '../script.dart';
|
||||
import '../universe/call_structure.dart';
|
||||
import 'source_file.dart';
|
||||
|
||||
/// Interface for passing source information, for instance for use in source
|
||||
|
@ -67,9 +68,14 @@ class SourceInformationBuilder<T> {
|
|||
/// Create a [SourceInformationBuilder] for [member].
|
||||
SourceInformationBuilder forContext(covariant MemberEntity member) => this;
|
||||
|
||||
/// Generate [SourceInformation] the declaration of the [member].
|
||||
/// Generate [SourceInformation] for the declaration of the [member].
|
||||
SourceInformation buildDeclaration(covariant MemberEntity member) => null;
|
||||
|
||||
/// Generate [SourceInformation] for the stub of [callStructure] for [member].
|
||||
SourceInformation buildStub(
|
||||
covariant FunctionEntity function, CallStructure callStructure) =>
|
||||
null;
|
||||
|
||||
/// Generate [SourceInformation] for the generic [node].
|
||||
@deprecated
|
||||
SourceInformation buildGeneric(T node) => null;
|
||||
|
@ -271,35 +277,41 @@ class OffsetSourceLocation extends AbstractSourceLocation {
|
|||
String toString() => '${super.toString()}:$sourceName';
|
||||
}
|
||||
|
||||
/// Compute the source map name for [element].
|
||||
String computeElementNameForSourceMaps(Entity element) {
|
||||
/// Compute the source map name for [element]. If [callStructure] is non-null
|
||||
/// it is used to name the parameter stub for [element].
|
||||
String computeElementNameForSourceMaps(Entity element,
|
||||
[CallStructure callStructure]) {
|
||||
if (element is AstElement) {
|
||||
return _computeAstElementNameForSourceMaps(element);
|
||||
return _computeAstElementNameForSourceMaps(element, callStructure);
|
||||
} else if (element is ClassEntity) {
|
||||
return element.name;
|
||||
} else if (element is MemberEntity) {
|
||||
String suffix = computeStubSuffix(callStructure);
|
||||
if (element is ConstructorEntity || element is ConstructorBodyEntity) {
|
||||
String className = element.enclosingClass.name;
|
||||
if (element.name == '') {
|
||||
return className;
|
||||
}
|
||||
return '$className.${element.name}';
|
||||
return '$className.${element.name}$suffix';
|
||||
} else if (element.enclosingClass != null) {
|
||||
if (element.enclosingClass.isClosure) {
|
||||
return computeElementNameForSourceMaps(element.enclosingClass);
|
||||
return computeElementNameForSourceMaps(
|
||||
element.enclosingClass, callStructure);
|
||||
}
|
||||
return '${element.enclosingClass.name}.${element.name}';
|
||||
return '${element.enclosingClass.name}.${element.name}$suffix';
|
||||
} else {
|
||||
return element.name;
|
||||
return '${element.name}$suffix';
|
||||
}
|
||||
}
|
||||
// TODO(redemption): Create element names from kernel locals and closures.
|
||||
return element.name;
|
||||
}
|
||||
|
||||
String _computeAstElementNameForSourceMaps(AstElement element) {
|
||||
String _computeAstElementNameForSourceMaps(
|
||||
AstElement element, CallStructure callStructure) {
|
||||
if (element.isClosure) {
|
||||
return computeElementNameForSourceMaps(element.enclosingElement);
|
||||
return computeElementNameForSourceMaps(
|
||||
element.enclosingElement, callStructure);
|
||||
} else if (element.isClass) {
|
||||
return element.name;
|
||||
} else if (element.isConstructor || element.isGenerativeConstructorBody) {
|
||||
|
@ -314,17 +326,36 @@ String _computeAstElementNameForSourceMaps(AstElement element) {
|
|||
if (name == '') {
|
||||
name = '<anonymous function>';
|
||||
}
|
||||
return '${computeElementNameForSourceMaps(local.executableContext)}.$name';
|
||||
String enclosingName =
|
||||
computeElementNameForSourceMaps(local.executableContext, callStructure);
|
||||
return '$enclosingName.$name';
|
||||
} else if (element.enclosingClass != null) {
|
||||
String suffix = computeStubSuffix(callStructure);
|
||||
if (element.enclosingClass.isClosure) {
|
||||
return computeElementNameForSourceMaps(element.enclosingClass);
|
||||
return computeElementNameForSourceMaps(
|
||||
element.enclosingClass, callStructure);
|
||||
}
|
||||
return '${element.enclosingClass.name}.${element.name}';
|
||||
return '${element.enclosingClass.name}.${element.name}$suffix';
|
||||
} else {
|
||||
return element.name;
|
||||
String suffix = computeStubSuffix(callStructure);
|
||||
return '${element.name}$suffix';
|
||||
}
|
||||
}
|
||||
|
||||
/// Compute the suffix used for a parameter stub for [callStructure].
|
||||
String computeStubSuffix(CallStructure callStructure) {
|
||||
if (callStructure == null) return '';
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.write(r'[function-entry$');
|
||||
sb.write(callStructure.positionalArgumentCount);
|
||||
if (callStructure.namedArguments.isNotEmpty) {
|
||||
sb.write(r'$');
|
||||
sb.write(callStructure.getOrderedNamedArguments().join(r'$'));
|
||||
}
|
||||
sb.write(']');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/// Computes the [SourceFile] for the source code of [resolvedAst].
|
||||
SourceFile computeSourceFile(ResolvedAst resolvedAst) {
|
||||
SourceFile sourceFile;
|
||||
|
|
|
@ -12,10 +12,11 @@ import 'package:front_end/src/fasta/scanner.dart' show Token;
|
|||
import '../common.dart';
|
||||
import '../diagnostics/messages.dart' show MessageTemplate;
|
||||
import '../elements/elements.dart'
|
||||
show MemberElement, ResolvedAst, ResolvedAstKind;
|
||||
show MemberElement, MethodElement, ResolvedAst, ResolvedAstKind;
|
||||
import '../js/js.dart' as js;
|
||||
import '../js/js_source_mapping.dart';
|
||||
import '../tree/tree.dart' show Node, Send;
|
||||
import '../universe/call_structure.dart';
|
||||
import 'source_file.dart';
|
||||
import 'source_information.dart';
|
||||
|
||||
|
@ -62,8 +63,10 @@ class StartEndSourceInformation extends SourceInformation {
|
|||
// TODO(johnniwinther): Inline this in
|
||||
// [StartEndSourceInformationBuilder.buildDeclaration].
|
||||
static StartEndSourceInformation _computeSourceInformation(
|
||||
ResolvedAst resolvedAst) {
|
||||
String name = computeElementNameForSourceMaps(resolvedAst.element);
|
||||
ResolvedAst resolvedAst,
|
||||
[CallStructure callStructure]) {
|
||||
String name =
|
||||
computeElementNameForSourceMaps(resolvedAst.element, callStructure);
|
||||
SourceFile sourceFile = computeSourceFile(resolvedAst);
|
||||
int begin;
|
||||
int end;
|
||||
|
@ -113,8 +116,9 @@ class StartEndSourceInformationStrategy
|
|||
const StartEndSourceInformationStrategy();
|
||||
|
||||
@override
|
||||
SourceInformationBuilder<Node> createBuilderForContext(MemberElement member) {
|
||||
return new StartEndSourceInformationBuilder(member);
|
||||
SourceInformationBuilder<Node> createBuilderForContext(MemberElement member,
|
||||
[CallStructure callStructure]) {
|
||||
return new StartEndSourceInformationBuilder(member, callStructure);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -193,15 +197,23 @@ class StartEndSourceInformationBuilder extends SourceInformationBuilder<Node> {
|
|||
final SourceFile sourceFile;
|
||||
final String name;
|
||||
|
||||
StartEndSourceInformationBuilder(MemberElement member)
|
||||
StartEndSourceInformationBuilder(MemberElement member,
|
||||
[CallStructure callStructure])
|
||||
: sourceFile = computeSourceFile(member.resolvedAst),
|
||||
name = computeElementNameForSourceMaps(member.resolvedAst.element);
|
||||
name = computeElementNameForSourceMaps(
|
||||
member.resolvedAst.element, callStructure);
|
||||
|
||||
SourceInformation buildDeclaration(MemberElement member) {
|
||||
return StartEndSourceInformation
|
||||
._computeSourceInformation(member.resolvedAst);
|
||||
}
|
||||
|
||||
SourceInformation buildStub(
|
||||
MethodElement member, CallStructure callStructure) {
|
||||
return StartEndSourceInformation._computeSourceInformation(
|
||||
member.resolvedAst, callStructure);
|
||||
}
|
||||
|
||||
SourceLocation sourceFileLocationForToken(Token token) {
|
||||
SourceLocation location =
|
||||
new OffsetSourceLocation(sourceFile, token.charOffset, name);
|
||||
|
|
|
@ -207,6 +207,7 @@ class CodeEmitterTask extends CompilerTask {
|
|||
namer,
|
||||
this,
|
||||
closedWorld,
|
||||
backend.sourceInformationStrategy,
|
||||
compiler.backendStrategy.sorter,
|
||||
typeTestRegistry.rtiNeededClasses,
|
||||
closedWorld.elementEnvironment.mainFunction,
|
||||
|
|
|
@ -7,6 +7,7 @@ library dart2js.js_emitter.parameter_stub_generator;
|
|||
import '../constants/values.dart';
|
||||
import '../elements/entities.dart';
|
||||
import '../elements/types.dart';
|
||||
import '../io/source_information.dart';
|
||||
import '../js/js.dart' as jsAst;
|
||||
import '../js/js.dart' show js;
|
||||
import '../js_backend/namer.dart' show Namer;
|
||||
|
@ -31,9 +32,16 @@ class ParameterStubGenerator {
|
|||
final InterceptorData _interceptorData;
|
||||
final CodegenWorldBuilder _codegenWorldBuilder;
|
||||
final ClosedWorld _closedWorld;
|
||||
final SourceInformationStrategy _sourceInformationStrategy;
|
||||
|
||||
ParameterStubGenerator(this._emitterTask, this._namer, this._nativeData,
|
||||
this._interceptorData, this._codegenWorldBuilder, this._closedWorld);
|
||||
ParameterStubGenerator(
|
||||
this._emitterTask,
|
||||
this._namer,
|
||||
this._nativeData,
|
||||
this._interceptorData,
|
||||
this._codegenWorldBuilder,
|
||||
this._closedWorld,
|
||||
this._sourceInformationStrategy);
|
||||
|
||||
Emitter get _emitter => _emitterTask.emitter;
|
||||
|
||||
|
@ -59,6 +67,11 @@ class ParameterStubGenerator {
|
|||
ParameterStubMethod generateParameterStub(
|
||||
FunctionEntity member, Selector selector, Selector callSelector) {
|
||||
CallStructure callStructure = selector.callStructure;
|
||||
SourceInformationBuilder sourceInformationBuilder =
|
||||
_sourceInformationStrategy.createBuilderForContext(member);
|
||||
SourceInformation sourceInformation =
|
||||
sourceInformationBuilder.buildStub(member, callStructure);
|
||||
|
||||
ParameterStructure parameterStructure = member.parameterStructure;
|
||||
int positionalArgumentCount = callStructure.positionalArgumentCount;
|
||||
bool needsTypeArguments =
|
||||
|
@ -182,7 +195,8 @@ class ParameterStubGenerator {
|
|||
[_emitter.staticFunctionAccess(member), argumentsBuffer]);
|
||||
}
|
||||
|
||||
jsAst.Fun function = js('function(#) { #; }', [parametersBuffer, body]);
|
||||
jsAst.Fun function = js('function(#) { #; }', [parametersBuffer, body])
|
||||
.withSourceInformation(sourceInformation);
|
||||
|
||||
jsAst.Name name = member.isStatic ? null : _namer.invocationName(selector);
|
||||
jsAst.Name callName =
|
||||
|
|
|
@ -19,6 +19,7 @@ import '../../elements/elements.dart'
|
|||
show ClassElement, FieldElement, LibraryElement, MethodElement;
|
||||
import '../../elements/entities.dart';
|
||||
import '../../elements/types.dart';
|
||||
import '../../io/source_information.dart';
|
||||
import '../../js/js.dart' as js;
|
||||
import '../../js_backend/backend.dart' show SuperMemberData;
|
||||
import '../../js_backend/backend_usage.dart';
|
||||
|
@ -89,6 +90,7 @@ class ProgramBuilder {
|
|||
final Namer _namer;
|
||||
final CodeEmitterTask _task;
|
||||
final ClosedWorld _closedWorld;
|
||||
final SourceInformationStrategy _sourceInformationStrategy;
|
||||
|
||||
/// The [Sorter] used for ordering elements in the generated JavaScript.
|
||||
final Sorter _sorter;
|
||||
|
@ -136,6 +138,7 @@ class ProgramBuilder {
|
|||
this._namer,
|
||||
this._task,
|
||||
this._closedWorld,
|
||||
this._sourceInformationStrategy,
|
||||
this._sorter,
|
||||
Set<ClassEntity> rtiNeededClasses,
|
||||
this._mainFunction,
|
||||
|
@ -976,8 +979,14 @@ class ProgramBuilder {
|
|||
FunctionEntity element, bool canTearOff) {
|
||||
if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[];
|
||||
|
||||
ParameterStubGenerator generator = new ParameterStubGenerator(_task, _namer,
|
||||
_nativeData, _interceptorData, _worldBuilder, _closedWorld);
|
||||
ParameterStubGenerator generator = new ParameterStubGenerator(
|
||||
_task,
|
||||
_namer,
|
||||
_nativeData,
|
||||
_interceptorData,
|
||||
_worldBuilder,
|
||||
_closedWorld,
|
||||
_sourceInformationStrategy);
|
||||
return generator.generateParameterStubs(element, canTearOff: canTearOff);
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,8 @@ Future testStackTrace(Test test, String config, CompileFunc compile,
|
|||
List<LineException> afterExceptions: const <LineException>[],
|
||||
bool useJsMethodNamesOnAbsence: false,
|
||||
String Function(String name) jsNameConverter: identityConverter,
|
||||
Directory forcedTmpDir: null}) async {
|
||||
Directory forcedTmpDir: null,
|
||||
int stackTraceLimit: 10}) async {
|
||||
Expect.isTrue(test.expectationMap.keys.contains(config),
|
||||
"No expectations found for '$config' in ${test.expectationMap.keys}");
|
||||
|
||||
|
@ -132,6 +133,8 @@ Future testStackTrace(Test test, String config, CompileFunc compile,
|
|||
}
|
||||
print("Running d8 $output");
|
||||
List<String> d8Arguments = <String>[];
|
||||
d8Arguments.add('--stack-trace-limit');
|
||||
d8Arguments.add('$stackTraceLimit');
|
||||
d8Arguments.addAll(jsPreambles(input, output));
|
||||
d8Arguments.add(output);
|
||||
ProcessResult runResult = Process.runSync(d8executable, d8Arguments);
|
||||
|
|
|
@ -648,7 +648,9 @@ class CodeLocation {
|
|||
final String name;
|
||||
final int offset;
|
||||
|
||||
CodeLocation(this.uri, this.name, this.offset);
|
||||
CodeLocation(this.uri, this.name, this.offset) {
|
||||
assert(uri != null);
|
||||
}
|
||||
|
||||
String toString() => '$uri:$name:$offset';
|
||||
|
||||
|
|
|
@ -180,6 +180,12 @@ checkNames(
|
|||
if (interval != null && interval.contains(sourcePosition)) {
|
||||
AstElement innerElement = findInnermost(element);
|
||||
String expectedName = computeElementNameForSourceMaps(innerElement);
|
||||
int stubIndex = name.indexOf('[function-entry');
|
||||
if (stubIndex != -1) {
|
||||
Expect.isTrue(innerElement is FunctionElement,
|
||||
"Unexpected element $innerElement for stub '$name'.");
|
||||
name = name.substring(0, stubIndex);
|
||||
}
|
||||
if (name != expectedName) {
|
||||
// For the code
|
||||
// (){}();
|
||||
|
|
76
tests/compiler/dart2js/sourcemaps/stacktrace/parameters.dart
Normal file
76
tests/compiler/dart2js/sourcemaps/stacktrace/parameters.dart
Normal file
|
@ -0,0 +1,76 @@
|
|||
// Copyright (c) 2018, 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:meta/dart2js.dart';
|
||||
|
||||
main() {
|
||||
var c = new Class();
|
||||
c. /*1:main*/ instancePositional1(0);
|
||||
}
|
||||
|
||||
class Class {
|
||||
@noInline
|
||||
/*2:Class.instancePositional1[function-entry$1]*/ instancePositional1(a,
|
||||
[b = 42, c = 87]) {
|
||||
print('instancePositional1($a,$b,$c)');
|
||||
/*3:Class.instancePositional1*/ instancePositional2(1, 2);
|
||||
}
|
||||
|
||||
@noInline
|
||||
/*4:Class.instancePositional2[function-entry$2]*/ instancePositional2(a,
|
||||
[b = 42, c = 87]) {
|
||||
print('instancePositional2($a,$b,$c)');
|
||||
/*5:Class.instancePositional2*/ instancePositional3(3, 4, 5);
|
||||
}
|
||||
|
||||
@noInline
|
||||
instancePositional3(a, [b = 42, c = 87]) {
|
||||
print('instancePositional3($a,$b,$c)');
|
||||
/*6:Class.instancePositional3*/ instanceNamed1(0);
|
||||
}
|
||||
|
||||
@noInline
|
||||
/*7:Class.instanceNamed1[function-entry$1]*/ instanceNamed1(a,
|
||||
{b: 42, c: 87, d: 735}) {
|
||||
print('instanceNamed1($a,b:$b,c:$c,d:$d)');
|
||||
/*8:Class.instanceNamed1*/ instanceNamed2(1, b: 2);
|
||||
}
|
||||
|
||||
@noInline
|
||||
/*9:Class.instanceNamed2[function-entry$1$b]*/ instanceNamed2(a,
|
||||
{b: 42, c: 87, d: 735}) {
|
||||
print('instanceNamed2($a,b:$b,c:$c,d:$d)');
|
||||
/*10:Class.instanceNamed2*/ instanceNamed3(3, c: 123);
|
||||
}
|
||||
|
||||
@noInline
|
||||
/*11:Class.instanceNamed3[function-entry$1$c]*/ instanceNamed3(a,
|
||||
{b: 42, c: 87, d: 735}) {
|
||||
print('instanceNamed3($a,b:$b,c:$c,d:$d)');
|
||||
/*12:Class.instanceNamed3*/ instanceNamed4(4, c: 45, b: 76);
|
||||
}
|
||||
|
||||
@noInline
|
||||
/*13:Class.instanceNamed4[function-entry$1$b$c]*/ instanceNamed4(a,
|
||||
{b: 42, c: 87, d: 735}) {
|
||||
print('instanceNamed4($a,b:$b,c:$c,d:$d)');
|
||||
/*14:Class.instanceNamed4*/ instanceNamed5(5, c: 6, b: 7, d: 8);
|
||||
}
|
||||
|
||||
@noInline
|
||||
instanceNamed5(a, {b: 42, c: 87, d: 735}) {
|
||||
print('instanceNamed5($a,b:$b,c:$c,d:$d)');
|
||||
/*18:Class.instanceNamed5[function-entry$0].local*/ local([e = 42]) {
|
||||
print('instanceNamed5.local($e)');
|
||||
/*19:Class.instanceNamed5.local*/ throw '>ExceptionMarker<';
|
||||
}
|
||||
|
||||
var anonymous = /*16:Class.instanceNamed5[function-entry$0].<anonymous function>*/ (
|
||||
{f: 87}) {
|
||||
print('instanceNamed5.<anonymous(f:$f)');
|
||||
/*17:Class.instanceNamed5.<anonymous function>*/ local();
|
||||
};
|
||||
anonymous. /*15:Class.instanceNamed5*/ call();
|
||||
}
|
||||
}
|
|
@ -92,7 +92,11 @@ Future runTest(Test test, String config,
|
|||
jsPreambles: (input, output) =>
|
||||
['sdk/lib/_internal/js_runtime/lib/preambles/d8.js'],
|
||||
afterExceptions: testAfterExceptions,
|
||||
beforeExceptions: beforeExceptions);
|
||||
beforeExceptions: beforeExceptions,
|
||||
verbose: verbose,
|
||||
printJs: printJs,
|
||||
writeJs: writeJs,
|
||||
stackTraceLimit: 100);
|
||||
}
|
||||
|
||||
/// Lines allowed before the intended stack trace. Typically from helper
|
||||
|
@ -119,4 +123,13 @@ const List<LineException> afterExceptions = const [
|
|||
const LineException('_Future._propagateToListeners', 'future_impl.dart'),
|
||||
const LineException(
|
||||
'_Future._addListener.<anonymous function>', 'future_impl.dart'),
|
||||
const LineException('_microtaskLoop', 'schedule_microtask.dart'),
|
||||
const LineException('_startMicrotaskLoop', 'schedule_microtask.dart'),
|
||||
const LineException('_AsyncRun._scheduleImmediateJsOverride.internalCallback',
|
||||
'async_patch.dart'),
|
||||
const LineException('invokeClosure.<anonymous function>', 'js_helper.dart'),
|
||||
const LineException('_IsolateContext.eval', 'isolate_helper.dart'),
|
||||
const LineException('_callInIsolate', 'isolate_helper.dart'),
|
||||
const LineException('invokeClosure', 'js_helper.dart'),
|
||||
const LineException('convertDartClosureToJS', 'js_helper.dart'),
|
||||
];
|
||||
|
|
|
@ -598,8 +598,9 @@ Source mapped Dart code</span><br/>
|
|||
</html>
|
||||
''');
|
||||
|
||||
new File(out).writeAsStringSync(sb.toString());
|
||||
print('Diff generated in $out');
|
||||
File file = new File(out);
|
||||
file.writeAsStringSync(sb.toString());
|
||||
print('Diff generated in ${file.absolute.uri}');
|
||||
}
|
||||
|
||||
class CodeLinesResult {
|
||||
|
@ -729,9 +730,11 @@ Future<CodeLinesResult> computeCodeLines(
|
|||
locations = [];
|
||||
}
|
||||
List<CodeLocation> codeLocations = locations
|
||||
.where((l) => l.sourceUri != null)
|
||||
.map((l) => new CodeLocation(l.sourceUri, l.sourceName, l.offset))
|
||||
.toList();
|
||||
List<CodeSource> codeSourceList = locations
|
||||
.where((l) => l.sourceUri != null)
|
||||
.map(codeSources.sourceLocationToCodeSource)
|
||||
.where((c) => c != null)
|
||||
.toList();
|
||||
|
|
|
@ -158,7 +158,7 @@ Future<TestResult> runTests(
|
|||
{bool verbose: true}) async {
|
||||
SourceMapProcessor processor = new SourceMapProcessor(uri);
|
||||
SourceMaps sourceMaps = await processor.process(
|
||||
['--csp', '--disable-inlining']..addAll(options),
|
||||
[Flags.useContentSecurityPolicy, Flags.disableInlining]..addAll(options),
|
||||
verbose: verbose);
|
||||
TestResult result = new TestResult(config, filename, processor);
|
||||
for (SourceMapInfo info in sourceMaps.elementSourceMapInfos.values) {
|
||||
|
|
Loading…
Reference in a new issue