Add startFileOffset on procedures et al, enable VMs GetSource
Prior to this change we only had fileOffset which points to the name. This CL adds a field - startFileOffset - that points to the start (e.g. 'static', 'factory', the return type or any presiding annotation (including '@')), as well as fixing `Function::GetSource` in the VM to fix a crash when using mirrors to ask for the source of a function or constructor. The field is added to procedures, constructors and classes. The latter changes the location of classes with annotations to be the position of the annotation. This is on-par with --no-preview-dart-2. The change in regards to procedures and constructors mean, that both the location and the source (from .location and .source on a MethodMirror) will change to include any annotations. This is a different behavior than --no-preview-dart-2. Closes #33271. Change-Id: I90f1232c5ec2d01e60e0bab070d44c37232b2730 Reviewed-on: https://dart-review.googlesource.com/60560 Commit-Queue: Jens Johansen <jensj@google.com> Reviewed-by: Kevin Millikin <kmillikin@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
52b2a869bc
commit
e2ce88dfcc
@@ -539,6 +539,7 @@ f() {
|
||||
formalParameterBuilders,
|
||||
kernel.ProcedureKind.Method,
|
||||
library,
|
||||
-1 /* startCharOffset */,
|
||||
-1 /* charOffset */,
|
||||
-1 /* charOpenParenOffset */,
|
||||
-1 /* charEndOffset */);
|
||||
|
||||
@@ -9,7 +9,8 @@ import 'builder.dart' show Declaration, TypeBuilder;
|
||||
import 'constructor_reference_builder.dart' show ConstructorReferenceBuilder;
|
||||
|
||||
abstract class MetadataBuilder<T extends TypeBuilder> {
|
||||
MetadataBuilder(Declaration parent, int charOffset);
|
||||
final int charOffset;
|
||||
MetadataBuilder(Declaration parent, this.charOffset);
|
||||
|
||||
factory MetadataBuilder.fromConstructor(
|
||||
ConstructorReferenceBuilder constructorReference,
|
||||
|
||||
@@ -84,9 +84,10 @@ class KernelEnumBuilder extends SourceClassBuilder
|
||||
this.objectType,
|
||||
this.stringType,
|
||||
LibraryBuilder parent,
|
||||
int startCharOffset,
|
||||
int charOffset)
|
||||
: super(metadata, 0, name, null, null, null, scope, constructors, parent,
|
||||
null, charOffset, TreeNode.noOffset, cls);
|
||||
null, startCharOffset, charOffset, TreeNode.noOffset, cls);
|
||||
|
||||
factory KernelEnumBuilder(
|
||||
MetadataCollector metadataCollector,
|
||||
@@ -140,6 +141,7 @@ class KernelEnumBuilder extends SourceClassBuilder
|
||||
parent,
|
||||
charOffset,
|
||||
charOffset,
|
||||
charOffset,
|
||||
charEndOffset);
|
||||
constructors[""] = constructorBuilder;
|
||||
KernelFieldBuilder valuesBuilder = new KernelFieldBuilder(null, listType,
|
||||
@@ -156,6 +158,7 @@ class KernelEnumBuilder extends SourceClassBuilder
|
||||
parent,
|
||||
charOffset,
|
||||
charOffset,
|
||||
charOffset,
|
||||
charEndOffset);
|
||||
members["toString"] = toStringBuilder;
|
||||
String className = name;
|
||||
@@ -192,6 +195,8 @@ class KernelEnumBuilder extends SourceClassBuilder
|
||||
fieldBuilder.target, documentationComment);
|
||||
members[name] = fieldBuilder;
|
||||
}
|
||||
final int startCharOffset =
|
||||
metadata == null ? charOffset : metadata.first.charOffset;
|
||||
KernelEnumBuilder enumBuilder = new KernelEnumBuilder.internal(
|
||||
metadata,
|
||||
name,
|
||||
@@ -206,6 +211,7 @@ class KernelEnumBuilder extends SourceClassBuilder
|
||||
objectType,
|
||||
stringType,
|
||||
parent,
|
||||
startCharOffset,
|
||||
charOffset);
|
||||
// TODO(sigmund): dynamic should be `covariant MemberBuilder`.
|
||||
void setParent(String name, dynamic b) {
|
||||
|
||||
@@ -180,6 +180,7 @@ class KernelLibraryBuilder
|
||||
List<TypeVariableBuilder> typeVariables,
|
||||
KernelTypeBuilder supertype,
|
||||
List<KernelTypeBuilder> interfaces,
|
||||
int startCharOffset,
|
||||
int charOffset,
|
||||
int charEndOffset,
|
||||
int supertypeOffset) {
|
||||
@@ -211,6 +212,7 @@ class KernelLibraryBuilder
|
||||
constructorScope,
|
||||
this,
|
||||
new List<ConstructorReferenceBuilder>.from(constructorReferences),
|
||||
startCharOffset,
|
||||
charOffset,
|
||||
charEndOffset);
|
||||
loader.target.metadataCollector
|
||||
@@ -441,6 +443,10 @@ class KernelLibraryBuilder
|
||||
}
|
||||
}
|
||||
}
|
||||
final int startCharOffset =
|
||||
(isNamedMixinApplication ? metadata : null) == null
|
||||
? charOffset
|
||||
: metadata.first.charOffset;
|
||||
SourceClassBuilder application = new SourceClassBuilder(
|
||||
isNamedMixinApplication ? metadata : null,
|
||||
isNamedMixinApplication
|
||||
@@ -457,6 +463,7 @@ class KernelLibraryBuilder
|
||||
isModifiable: false),
|
||||
this,
|
||||
<ConstructorReferenceBuilder>[],
|
||||
startCharOffset,
|
||||
charOffset,
|
||||
TreeNode.noOffset,
|
||||
null,
|
||||
@@ -527,6 +534,7 @@ class KernelLibraryBuilder
|
||||
String constructorName,
|
||||
List<TypeVariableBuilder> typeVariables,
|
||||
List<FormalParameterBuilder> formals,
|
||||
int startCharOffset,
|
||||
int charOffset,
|
||||
int charOpenParenOffset,
|
||||
int charEndOffset,
|
||||
@@ -540,6 +548,7 @@ class KernelLibraryBuilder
|
||||
typeVariables,
|
||||
formals,
|
||||
this,
|
||||
startCharOffset,
|
||||
charOffset,
|
||||
charOpenParenOffset,
|
||||
charEndOffset,
|
||||
@@ -563,6 +572,7 @@ class KernelLibraryBuilder
|
||||
List<TypeVariableBuilder> typeVariables,
|
||||
List<FormalParameterBuilder> formals,
|
||||
ProcedureKind kind,
|
||||
int startCharOffset,
|
||||
int charOffset,
|
||||
int charOpenParenOffset,
|
||||
int charEndOffset,
|
||||
@@ -578,6 +588,7 @@ class KernelLibraryBuilder
|
||||
formals,
|
||||
kind,
|
||||
this,
|
||||
startCharOffset,
|
||||
charOffset,
|
||||
charOpenParenOffset,
|
||||
charEndOffset,
|
||||
@@ -598,6 +609,7 @@ class KernelLibraryBuilder
|
||||
Object name,
|
||||
List<FormalParameterBuilder> formals,
|
||||
ConstructorReferenceBuilder redirectionTarget,
|
||||
int startCharOffset,
|
||||
int charOffset,
|
||||
int charOpenParenOffset,
|
||||
int charEndOffset,
|
||||
@@ -630,6 +642,7 @@ class KernelLibraryBuilder
|
||||
factoryDeclaration),
|
||||
formals,
|
||||
this,
|
||||
startCharOffset,
|
||||
charOffset,
|
||||
charOpenParenOffset,
|
||||
charEndOffset,
|
||||
@@ -647,6 +660,7 @@ class KernelLibraryBuilder
|
||||
formals,
|
||||
ProcedureKind.Factory,
|
||||
this,
|
||||
startCharOffset,
|
||||
charOffset,
|
||||
charOpenParenOffset,
|
||||
charEndOffset,
|
||||
|
||||
@@ -271,12 +271,14 @@ class KernelProcedureBuilder extends KernelFunctionBuilder {
|
||||
List<FormalParameterBuilder> formals,
|
||||
ProcedureKind kind,
|
||||
KernelLibraryBuilder compilationUnit,
|
||||
int startCharOffset,
|
||||
int charOffset,
|
||||
this.charOpenParenOffset,
|
||||
int charEndOffset,
|
||||
[String nativeMethodName])
|
||||
: procedure = new ShadowProcedure(null, kind, null, returnType == null,
|
||||
fileUri: compilationUnit?.fileUri)
|
||||
..startFileOffset = startCharOffset
|
||||
..fileOffset = charOffset
|
||||
..fileEndOffset = charEndOffset,
|
||||
super(metadata, modifiers, returnType, name, typeVariables, formals,
|
||||
@@ -367,6 +369,7 @@ class KernelProcedureBuilder extends KernelFunctionBuilder {
|
||||
// TODO(ahe): restore file-offset once we track both origin and patch file
|
||||
// URIs. See https://github.com/dart-lang/sdk/issues/31579
|
||||
origin.procedure.fileUri = fileUri;
|
||||
origin.procedure.startFileOffset = procedure.startFileOffset;
|
||||
origin.procedure.fileOffset = procedure.fileOffset;
|
||||
origin.procedure.fileEndOffset = procedure.fileEndOffset;
|
||||
origin.procedure.annotations
|
||||
@@ -420,11 +423,13 @@ class KernelConstructorBuilder extends KernelFunctionBuilder {
|
||||
List<TypeVariableBuilder> typeVariables,
|
||||
List<FormalParameterBuilder> formals,
|
||||
KernelLibraryBuilder compilationUnit,
|
||||
int startCharOffset,
|
||||
int charOffset,
|
||||
this.charOpenParenOffset,
|
||||
int charEndOffset,
|
||||
[String nativeMethodName])
|
||||
: constructor = new Constructor(null, fileUri: compilationUnit?.fileUri)
|
||||
..startFileOffset = startCharOffset
|
||||
..fileOffset = charOffset
|
||||
..fileEndOffset = charEndOffset,
|
||||
super(metadata, modifiers, returnType, name, typeVariables, formals,
|
||||
@@ -555,6 +560,7 @@ class KernelConstructorBuilder extends KernelFunctionBuilder {
|
||||
// TODO(ahe): restore file-offset once we track both origin and patch file
|
||||
// URIs. See https://github.com/dart-lang/sdk/issues/31579
|
||||
origin.constructor.fileUri = fileUri;
|
||||
origin.constructor.startFileOffset = constructor.startFileOffset;
|
||||
origin.constructor.fileOffset = constructor.fileOffset;
|
||||
origin.constructor.fileEndOffset = constructor.fileEndOffset;
|
||||
origin.constructor.annotations
|
||||
@@ -598,6 +604,7 @@ class KernelRedirectingFactoryBuilder extends KernelProcedureBuilder {
|
||||
List<TypeVariableBuilder> typeVariables,
|
||||
List<FormalParameterBuilder> formals,
|
||||
KernelLibraryBuilder compilationUnit,
|
||||
int startCharOffset,
|
||||
int charOffset,
|
||||
int charOpenParenOffset,
|
||||
int charEndOffset,
|
||||
@@ -612,6 +619,7 @@ class KernelRedirectingFactoryBuilder extends KernelProcedureBuilder {
|
||||
formals,
|
||||
ProcedureKind.Factory,
|
||||
compilationUnit,
|
||||
startCharOffset,
|
||||
charOffset,
|
||||
charOpenParenOffset,
|
||||
charEndOffset,
|
||||
|
||||
@@ -343,8 +343,19 @@ class KernelTarget extends TargetImplementation {
|
||||
// method. Similarly considerations apply to separate compilation. It
|
||||
// could also make sense to add a way to mark .dill files as having
|
||||
// compile-time errors.
|
||||
KernelProcedureBuilder mainBuilder = new KernelProcedureBuilder(null, 0,
|
||||
null, "#main", null, null, ProcedureKind.Method, library, -1, -1, -1);
|
||||
KernelProcedureBuilder mainBuilder = new KernelProcedureBuilder(
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
"#main",
|
||||
null,
|
||||
null,
|
||||
ProcedureKind.Method,
|
||||
library,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1);
|
||||
library.addBuilder(mainBuilder.name, mainBuilder, -1);
|
||||
mainBuilder.body = new Block(new List<Statement>.from(errors.map(
|
||||
(LocatedMessage message) => new ExpressionStatement(new Throw(
|
||||
|
||||
@@ -53,6 +53,7 @@ class LoadLibraryBuilder extends Declaration {
|
||||
<DartType>[const DynamicType()])),
|
||||
fileUri: parent.target.fileUri,
|
||||
isStatic: true)
|
||||
..startFileOffset = charOffset
|
||||
..fileOffset = charOffset;
|
||||
return tearoff;
|
||||
}
|
||||
|
||||
@@ -130,10 +130,10 @@ class OutlineBuilder extends StackListener {
|
||||
String postfix = popIfNotNull(periodBeforeName);
|
||||
List<TypeBuilder> typeArguments = pop();
|
||||
if (arguments == null) {
|
||||
int charOffset = pop();
|
||||
pop(); // charOffset
|
||||
Object expression = pop();
|
||||
push(new MetadataBuilder.fromExpression(
|
||||
expression, postfix, library, charOffset));
|
||||
expression, postfix, library, beginToken.charOffset));
|
||||
} else {
|
||||
int charOffset = pop();
|
||||
Object typeName = pop();
|
||||
@@ -465,6 +465,9 @@ class OutlineBuilder extends StackListener {
|
||||
}
|
||||
List<MetadataBuilder> metadata = pop();
|
||||
|
||||
final int startCharOffset =
|
||||
metadata == null ? beginToken.charOffset : metadata.first.charOffset;
|
||||
|
||||
library.addClass(
|
||||
documentationComment,
|
||||
metadata,
|
||||
@@ -473,6 +476,7 @@ class OutlineBuilder extends StackListener {
|
||||
typeVariables,
|
||||
supertype,
|
||||
interfaces,
|
||||
startCharOffset,
|
||||
charOffset,
|
||||
endToken.charOffset,
|
||||
supertypeOffset);
|
||||
@@ -521,6 +525,8 @@ class OutlineBuilder extends StackListener {
|
||||
library
|
||||
.endNestedDeclaration("#method")
|
||||
.resolveTypes(typeVariables, library);
|
||||
final int startCharOffset =
|
||||
metadata == null ? beginToken.charOffset : metadata.first.charOffset;
|
||||
library.addProcedure(
|
||||
documentationComment,
|
||||
metadata,
|
||||
@@ -530,6 +536,7 @@ class OutlineBuilder extends StackListener {
|
||||
typeVariables,
|
||||
formals,
|
||||
computeProcedureKind(getOrSet),
|
||||
startCharOffset,
|
||||
charOffset,
|
||||
formalsOffset,
|
||||
endToken.charOffset,
|
||||
@@ -710,6 +717,8 @@ class OutlineBuilder extends StackListener {
|
||||
messageConstructorWithReturnType, beginToken, beginToken);
|
||||
returnType = null;
|
||||
}
|
||||
final int startCharOffset =
|
||||
metadata == null ? beginToken.charOffset : metadata.first.charOffset;
|
||||
library.addConstructor(
|
||||
documentationComment,
|
||||
metadata,
|
||||
@@ -719,6 +728,7 @@ class OutlineBuilder extends StackListener {
|
||||
constructorName,
|
||||
typeVariables,
|
||||
formals,
|
||||
startCharOffset,
|
||||
charOffset,
|
||||
formalsOffset,
|
||||
endToken.charOffset,
|
||||
@@ -728,6 +738,8 @@ class OutlineBuilder extends StackListener {
|
||||
addCompileTimeError(messageConstMethod, varFinalOrConstOffset, 5);
|
||||
modifiers &= ~constMask;
|
||||
}
|
||||
final int startCharOffset =
|
||||
metadata == null ? beginToken.charOffset : metadata.first.charOffset;
|
||||
library.addProcedure(
|
||||
documentationComment,
|
||||
metadata,
|
||||
@@ -737,6 +749,7 @@ class OutlineBuilder extends StackListener {
|
||||
typeVariables,
|
||||
formals,
|
||||
kind,
|
||||
startCharOffset,
|
||||
charOffset,
|
||||
formalsOffset,
|
||||
endToken.charOffset,
|
||||
@@ -1183,6 +1196,7 @@ class OutlineBuilder extends StackListener {
|
||||
name,
|
||||
formals,
|
||||
redirectionTarget,
|
||||
beginToken.charOffset,
|
||||
charOffset,
|
||||
formalsOffset,
|
||||
endToken.charOffset,
|
||||
|
||||
@@ -47,10 +47,14 @@ ShadowClass initializeClass(
|
||||
List<TypeVariableBuilder> typeVariables,
|
||||
String name,
|
||||
KernelLibraryBuilder parent,
|
||||
int startCharOffset,
|
||||
int charOffset,
|
||||
int charEndOffset) {
|
||||
cls ??= new ShadowClass(name: name);
|
||||
cls.fileUri ??= parent.fileUri;
|
||||
if (cls.startFileOffset == TreeNode.noOffset) {
|
||||
cls.startFileOffset = startCharOffset;
|
||||
}
|
||||
if (cls.fileOffset == TreeNode.noOffset) {
|
||||
cls.fileOffset = charOffset;
|
||||
}
|
||||
@@ -87,12 +91,13 @@ class SourceClassBuilder extends KernelClassBuilder {
|
||||
Scope constructors,
|
||||
LibraryBuilder parent,
|
||||
this.constructorReferences,
|
||||
int startCharOffset,
|
||||
int charOffset,
|
||||
int charEndOffset,
|
||||
[ShadowClass cls,
|
||||
this.mixedInType])
|
||||
: actualCls = initializeClass(
|
||||
cls, typeVariables, name, parent, charOffset, charEndOffset),
|
||||
: actualCls = initializeClass(cls, typeVariables, name, parent,
|
||||
startCharOffset, charOffset, charEndOffset),
|
||||
super(metadata, modifiers, name, typeVariables, supertype, interfaces,
|
||||
scope, constructors, parent, charOffset) {
|
||||
ShadowClass.setBuilder(this.cls, this);
|
||||
|
||||
@@ -338,6 +338,7 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
||||
List<TypeVariableBuilder> typeVariables,
|
||||
T supertype,
|
||||
List<T> interfaces,
|
||||
int startCharOffset,
|
||||
int charOffset,
|
||||
int charEndOffset,
|
||||
int supertypeOffset);
|
||||
@@ -388,6 +389,7 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
||||
String constructorName,
|
||||
List<TypeVariableBuilder> typeVariables,
|
||||
List<FormalParameterBuilder> formals,
|
||||
int startCharOffset,
|
||||
int charOffset,
|
||||
int charOpenParenOffset,
|
||||
int charEndOffset,
|
||||
@@ -402,6 +404,7 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
||||
List<TypeVariableBuilder> typeVariables,
|
||||
List<FormalParameterBuilder> formals,
|
||||
ProcedureKind kind,
|
||||
int startCharOffset,
|
||||
int charOffset,
|
||||
int charOpenParenOffset,
|
||||
int charEndOffset,
|
||||
@@ -437,6 +440,7 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
||||
Object name,
|
||||
List<FormalParameterBuilder> formals,
|
||||
ConstructorReferenceBuilder redirectionTarget,
|
||||
int startCharOffset,
|
||||
int charOffset,
|
||||
int charOpenParenOffset,
|
||||
int charEndOffset,
|
||||
|
||||
@@ -243,7 +243,7 @@ class SourceLoader<L> extends Loader<L> {
|
||||
}
|
||||
}
|
||||
KernelProcedureBuilder builder = new KernelProcedureBuilder(null, 0, null,
|
||||
"debugExpr", null, null, ProcedureKind.Method, library, 0, -1, -1)
|
||||
"debugExpr", null, null, ProcedureKind.Method, library, 0, 0, -1, -1)
|
||||
..parent = parent;
|
||||
BodyBuilder listener = dietListener.createListener(
|
||||
builder, dietListener.memberScope, isInstanceMember);
|
||||
|
||||
@@ -537,6 +537,7 @@ class ForwardingNode extends Procedure {
|
||||
isForwardingStub: true,
|
||||
fileUri: enclosingClass.fileUri,
|
||||
forwardingStubInterfaceTarget: finalTarget)
|
||||
..startFileOffset = enclosingClass.fileOffset
|
||||
..fileOffset = enclosingClass.fileOffset
|
||||
..parent = enclosingClass;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ class MockLibraryBuilder extends KernelLibraryBuilder {
|
||||
|
||||
KernelProcedureBuilder mockProcedure(String name) {
|
||||
return new KernelProcedureBuilder(null, 0, null, name, null, null,
|
||||
ProcedureKind.Getter, this, -1, -1, -1);
|
||||
ProcedureKind.Getter, this, -1, -1, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -284,7 +284,8 @@ type Class extends Node {
|
||||
CanonicalNameReference canonicalName;
|
||||
// An absolute path URI to the .dart file from which the class was created.
|
||||
UriReference fileUri;
|
||||
FileOffset fileOffset;
|
||||
FileOffset startFileOffset; // Offset of the start of the class including any annotations.
|
||||
FileOffset fileOffset; // Offset of the name of the class.
|
||||
FileOffset fileEndOffset;
|
||||
Byte flags (levelBit0, levelBit1, isAbstract, isEnum, isAnonymousMixin,
|
||||
isEliminatedMixin); // Where level is index into ClassLevel
|
||||
@@ -328,7 +329,8 @@ type Constructor extends Member {
|
||||
Byte tag = 5;
|
||||
CanonicalNameReference canonicalName;
|
||||
UriReference fileUri;
|
||||
FileOffset fileOffset;
|
||||
FileOffset startFileOffset; // Offset of the start of the constructor including any annotations.
|
||||
FileOffset fileOffset; // Offset of the constructor name.
|
||||
FileOffset fileEndOffset;
|
||||
Byte flags (isConst, isExternal, isSynthetic);
|
||||
Name name;
|
||||
@@ -352,7 +354,8 @@ type Procedure extends Member {
|
||||
CanonicalNameReference canonicalName;
|
||||
// An absolute path URI to the .dart file from which the class was created.
|
||||
UriReference fileUri;
|
||||
FileOffset fileOffset;
|
||||
FileOffset startFileOffset; // Offset of the start of the procedure including any annotations.
|
||||
FileOffset fileOffset; // Offset of the procedure name.
|
||||
FileOffset fileEndOffset;
|
||||
Byte kind; // Index into the ProcedureKind enum above.
|
||||
Byte flags (isStatic, isAbstract, isExternal, isConst, isForwardingStub,
|
||||
|
||||
+32
-3
@@ -672,6 +672,15 @@ enum ClassLevel {
|
||||
/// transform a mixin application to become a regular class, and vice versa.
|
||||
@coq
|
||||
class Class extends NamedNode implements FileUriNode {
|
||||
/// Start offset of the class in the source file it comes from.
|
||||
///
|
||||
/// Note that this includes annotations if any.
|
||||
///
|
||||
/// Valid values are from 0 and up, or -1 ([TreeNode.noOffset]) if the file
|
||||
/// start offset is not available (this is the default if none is specifically
|
||||
/// set).
|
||||
int startFileOffset = TreeNode.noOffset;
|
||||
|
||||
/// End offset in the source file it comes from. Valid values are from 0 and
|
||||
/// up, or -1 ([TreeNode.noOffset]) if the file end offset is not available
|
||||
/// (this is the default if none is specifically set).
|
||||
@@ -973,9 +982,11 @@ class Class extends NamedNode implements FileUriNode {
|
||||
|
||||
@coq
|
||||
abstract class Member extends NamedNode implements FileUriNode {
|
||||
/// End offset in the source file it comes from. Valid values are from 0 and
|
||||
/// up, or -1 ([TreeNode.noOffset]) if the file end offset is not available
|
||||
/// (this is the default if none is specifically set).
|
||||
/// End offset in the source file it comes from.
|
||||
///
|
||||
/// Valid values are from 0 and up, or -1 ([TreeNode.noOffset]) if the file
|
||||
/// end offset is not available (this is the default if none is specifically
|
||||
/// set).
|
||||
int fileEndOffset = TreeNode.noOffset;
|
||||
|
||||
/// List of metadata annotations on the member.
|
||||
@@ -1224,6 +1235,15 @@ class Field extends Member {
|
||||
///
|
||||
/// For unnamed constructors, the name is an empty string (in a [Name]).
|
||||
class Constructor extends Member {
|
||||
/// Start offset of the constructor in the source file it comes from.
|
||||
///
|
||||
/// Note that this includes annotations if any.
|
||||
///
|
||||
/// Valid values are from 0 and up, or -1 ([TreeNode.noOffset]) if the file
|
||||
/// start offset is not available (this is the default if none is specifically
|
||||
/// set).
|
||||
int startFileOffset = TreeNode.noOffset;
|
||||
|
||||
int flags = 0;
|
||||
FunctionNode function;
|
||||
List<Initializer> initializers;
|
||||
@@ -1450,6 +1470,15 @@ class RedirectingFactoryConstructor extends Member {
|
||||
/// except for the unary minus operator, whose name is `unary-`.
|
||||
@coq
|
||||
class Procedure extends Member {
|
||||
/// Start offset of the function in the source file it comes from.
|
||||
///
|
||||
/// Note that this includes annotations if any.
|
||||
///
|
||||
/// Valid values are from 0 and up, or -1 ([TreeNode.noOffset]) if the file
|
||||
/// start offset is not available (this is the default if none is specifically
|
||||
/// set).
|
||||
int startFileOffset = TreeNode.noOffset;
|
||||
|
||||
ProcedureKind kind;
|
||||
int flags = 0;
|
||||
// function is null if and only if abstract, external.
|
||||
|
||||
@@ -904,6 +904,7 @@ class BinaryBuilder {
|
||||
}
|
||||
|
||||
var fileUri = readUriReference();
|
||||
node.startFileOffset = readOffset();
|
||||
node.fileOffset = readOffset();
|
||||
node.fileEndOffset = readOffset();
|
||||
int flags = readByte();
|
||||
@@ -1013,6 +1014,7 @@ class BinaryBuilder {
|
||||
node = new Constructor(null, reference: reference);
|
||||
}
|
||||
var fileUri = readUriReference();
|
||||
var startFileOffset = readOffset();
|
||||
var fileOffset = readOffset();
|
||||
var fileEndOffset = readOffset();
|
||||
var flags = readByte();
|
||||
@@ -1034,6 +1036,7 @@ class BinaryBuilder {
|
||||
var transformerFlags = getAndResetTransformerFlags();
|
||||
assert(((_) => true)(debugPath.removeLast()));
|
||||
if (shouldWriteData) {
|
||||
node.startFileOffset = startFileOffset;
|
||||
node.fileOffset = fileOffset;
|
||||
node.fileEndOffset = fileEndOffset;
|
||||
node.flags = flags;
|
||||
@@ -1057,6 +1060,7 @@ class BinaryBuilder {
|
||||
node = new Procedure(null, null, null, reference: reference);
|
||||
}
|
||||
var fileUri = readUriReference();
|
||||
var startFileOffset = readOffset();
|
||||
var fileOffset = readOffset();
|
||||
var fileEndOffset = readOffset();
|
||||
int kindIndex = readByte();
|
||||
@@ -1081,6 +1085,7 @@ class BinaryBuilder {
|
||||
var transformerFlags = getAndResetTransformerFlags();
|
||||
assert(((_) => true)(debugPath.removeLast()));
|
||||
if (shouldWriteData) {
|
||||
node.startFileOffset = startFileOffset;
|
||||
node.fileOffset = fileOffset;
|
||||
node.fileEndOffset = fileEndOffset;
|
||||
node.kind = kind;
|
||||
|
||||
@@ -746,8 +746,10 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
||||
final Uri activeFileUriSaved = _activeFileUri;
|
||||
_activeFileUri = writeUriReference(node.fileUri);
|
||||
|
||||
writeOffset(node.startFileOffset);
|
||||
writeOffset(node.fileOffset);
|
||||
writeOffset(node.fileEndOffset);
|
||||
|
||||
writeByte(flags);
|
||||
writeStringReference(node.name ?? '');
|
||||
|
||||
@@ -788,8 +790,10 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
||||
final Uri activeFileUriSaved = _activeFileUri;
|
||||
_activeFileUri = writeUriReference(node.fileUri);
|
||||
|
||||
writeOffset(node.startFileOffset);
|
||||
writeOffset(node.fileOffset);
|
||||
writeOffset(node.fileEndOffset);
|
||||
|
||||
writeByte(node.flags);
|
||||
writeName(node.name ?? _emptyName);
|
||||
|
||||
@@ -820,6 +824,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
||||
final Uri activeFileUriSaved = _activeFileUri;
|
||||
_activeFileUri = writeUriReference(node.fileUri);
|
||||
|
||||
writeOffset(node.startFileOffset);
|
||||
writeOffset(node.fileOffset);
|
||||
writeOffset(node.fileEndOffset);
|
||||
writeByte(node.kind.index);
|
||||
|
||||
@@ -440,6 +440,7 @@ class CloneVisitor implements TreeVisitor {
|
||||
..annotations = cloneAnnotations && !node.annotations.isEmpty
|
||||
? node.annotations.map(clone).toList()
|
||||
: const <Expression>[]
|
||||
..startFileOffset = _cloneFileOffset(node.startFileOffset)
|
||||
..fileOffset = _cloneFileOffset(node.fileOffset)
|
||||
..fileEndOffset = _cloneFileOffset(node.fileEndOffset)
|
||||
..flags = node.flags;
|
||||
|
||||
@@ -45,12 +45,12 @@ var tests = <IsolateTest>[
|
||||
|
||||
var expectedRange = {
|
||||
'scriptIndex': 0,
|
||||
'startPos': ifKernel(456, 26),
|
||||
'startPos': ifKernel(449, 26),
|
||||
'endPos': ifKernel(499, 38),
|
||||
'compiled': true,
|
||||
'coverage': {
|
||||
'hits': ifKernel([], []),
|
||||
'misses': ifKernel([456], [26])
|
||||
'misses': ifKernel([449], [26])
|
||||
}
|
||||
};
|
||||
|
||||
@@ -86,11 +86,11 @@ var tests = <IsolateTest>[
|
||||
|
||||
var expectedRange = {
|
||||
'scriptIndex': 0,
|
||||
'startPos': ifKernel(456, 26),
|
||||
'startPos': ifKernel(449, 26),
|
||||
'endPos': ifKernel(499, 38),
|
||||
'compiled': true,
|
||||
'coverage': {
|
||||
'hits': ifKernel([456], [26]),
|
||||
'hits': ifKernel([449], [26]),
|
||||
'misses': ifKernel([], [])
|
||||
}
|
||||
};
|
||||
|
||||
@@ -37,11 +37,11 @@ var tests = <IsolateTest>[
|
||||
|
||||
var expectedRange = {
|
||||
'scriptIndex': 0,
|
||||
'startPos': ifKernel(476, 26),
|
||||
'startPos': ifKernel(469, 26),
|
||||
'endPos': ifKernel(536, 51),
|
||||
'compiled': true,
|
||||
'coverage': {
|
||||
'hits': ifKernel([476, 509, 520, 524], [26, 37, 41, 45]),
|
||||
'hits': ifKernel([469, 509, 520, 524], [26, 37, 41, 45]),
|
||||
'misses': ifKernel([], [])
|
||||
}
|
||||
};
|
||||
|
||||
@@ -61,11 +61,11 @@ var tests = <IsolateTest>[
|
||||
|
||||
var expectedRange = {
|
||||
'scriptIndex': 0,
|
||||
'startPos': ifKernel(501, 40),
|
||||
'startPos': ifKernel(489, 40),
|
||||
'endPos': ifKernel(633, 89),
|
||||
'compiled': true,
|
||||
'coverage': {
|
||||
'hits': ifKernel([501, 539, 590, 619], [40, 55, 73, 83]),
|
||||
'hits': ifKernel([489, 539, 590, 619], [40, 55, 73, 83]),
|
||||
'misses': ifKernel([552], [61])
|
||||
}
|
||||
};
|
||||
|
||||
@@ -272,6 +272,11 @@ void ProcedureHelper::ReadUntilExcluding(Field field) {
|
||||
helper_->set_current_script_id(source_uri_index_);
|
||||
if (++next_read_ == field) return;
|
||||
/* Falls through */
|
||||
case kStartPosition:
|
||||
start_position_ = helper_->ReadPosition(false); // read position.
|
||||
helper_->RecordTokenPosition(start_position_);
|
||||
if (++next_read_ == field) return;
|
||||
/* Falls through */
|
||||
case kPosition:
|
||||
position_ = helper_->ReadPosition(false); // read position.
|
||||
helper_->RecordTokenPosition(position_);
|
||||
@@ -345,6 +350,11 @@ void ConstructorHelper::ReadUntilExcluding(Field field) {
|
||||
helper_->set_current_script_id(source_uri_index_);
|
||||
if (++next_read_ == field) return;
|
||||
/* Falls through */
|
||||
case kStartPosition:
|
||||
start_position_ = helper_->ReadPosition(); // read position.
|
||||
helper_->RecordTokenPosition(start_position_);
|
||||
if (++next_read_ == field) return;
|
||||
/* Falls through */
|
||||
case kPosition:
|
||||
position_ = helper_->ReadPosition(); // read position.
|
||||
helper_->RecordTokenPosition(position_);
|
||||
@@ -410,6 +420,11 @@ void ClassHelper::ReadUntilExcluding(Field field) {
|
||||
helper_->set_current_script_id(source_uri_index_);
|
||||
if (++next_read_ == field) return;
|
||||
/* Falls through */
|
||||
case kStartPosition:
|
||||
start_position_ = helper_->ReadPosition(false); // read position.
|
||||
helper_->RecordTokenPosition(start_position_);
|
||||
if (++next_read_ == field) return;
|
||||
/* Falls through */
|
||||
case kPosition:
|
||||
position_ = helper_->ReadPosition(false); // read position.
|
||||
helper_->RecordTokenPosition(position_);
|
||||
|
||||
@@ -275,6 +275,7 @@ class ProcedureHelper {
|
||||
kStart, // tag.
|
||||
kCanonicalName,
|
||||
kSourceUriIndex,
|
||||
kStartPosition,
|
||||
kPosition,
|
||||
kEndPosition,
|
||||
kKind,
|
||||
@@ -329,6 +330,7 @@ class ProcedureHelper {
|
||||
}
|
||||
|
||||
NameIndex canonical_name_;
|
||||
TokenPosition start_position_;
|
||||
TokenPosition position_;
|
||||
TokenPosition end_position_;
|
||||
Kind kind_;
|
||||
@@ -357,6 +359,7 @@ class ConstructorHelper {
|
||||
kStart, // tag.
|
||||
kCanonicalName,
|
||||
kSourceUriIndex,
|
||||
kStartPosition,
|
||||
kPosition,
|
||||
kEndPosition,
|
||||
kFlags,
|
||||
@@ -390,6 +393,7 @@ class ConstructorHelper {
|
||||
bool IsSynthetic() { return (flags_ & kSynthetic) != 0; }
|
||||
|
||||
NameIndex canonical_name_;
|
||||
TokenPosition start_position_;
|
||||
TokenPosition position_;
|
||||
TokenPosition end_position_;
|
||||
uint8_t flags_;
|
||||
@@ -414,6 +418,7 @@ class ClassHelper {
|
||||
kStart, // tag.
|
||||
kCanonicalName,
|
||||
kSourceUriIndex,
|
||||
kStartPosition,
|
||||
kPosition,
|
||||
kEndPosition,
|
||||
kFlags,
|
||||
@@ -458,6 +463,7 @@ class ClassHelper {
|
||||
}
|
||||
|
||||
NameIndex canonical_name_;
|
||||
TokenPosition start_position_;
|
||||
TokenPosition position_;
|
||||
TokenPosition end_position_;
|
||||
StringIndex name_index_;
|
||||
|
||||
@@ -259,7 +259,7 @@ void VerifyStackOverflowStackTraceInfo(const char* script,
|
||||
|
||||
TEST_CASE(DartAPI_StackOverflowStackTraceInfoBraceFunction1) {
|
||||
int line = 2;
|
||||
int col = FLAG_use_dart_frontend ? 10 : 3;
|
||||
int col = 3;
|
||||
VerifyStackOverflowStackTraceInfo(
|
||||
"class C {\n"
|
||||
" static foo(int i) { foo(i); }\n"
|
||||
@@ -270,7 +270,7 @@ TEST_CASE(DartAPI_StackOverflowStackTraceInfoBraceFunction1) {
|
||||
|
||||
TEST_CASE(DartAPI_StackOverflowStackTraceInfoBraceFunction2) {
|
||||
int line = 2;
|
||||
int col = FLAG_use_dart_frontend ? 10 : 3;
|
||||
int col = 3;
|
||||
VerifyStackOverflowStackTraceInfo(
|
||||
"class C {\n"
|
||||
" static foo(int i, int j) {\n"
|
||||
@@ -283,7 +283,7 @@ TEST_CASE(DartAPI_StackOverflowStackTraceInfoBraceFunction2) {
|
||||
|
||||
TEST_CASE(DartAPI_StackOverflowStackTraceInfoArrowFunction) {
|
||||
int line = 2;
|
||||
int col = FLAG_use_dart_frontend ? 10 : 3;
|
||||
int col = 3;
|
||||
VerifyStackOverflowStackTraceInfo(
|
||||
"class C {\n"
|
||||
" static foo(int i) => foo(i);\n"
|
||||
|
||||
@@ -1092,8 +1092,8 @@ Class& KernelLoader::LoadClass(const Library& library,
|
||||
FixCoreLibraryScriptUri(library, script);
|
||||
}
|
||||
if (klass.token_pos() == TokenPosition::kNoSource) {
|
||||
class_helper.ReadUntilIncluding(ClassHelper::kPosition);
|
||||
klass.set_token_pos(class_helper.position_);
|
||||
class_helper.ReadUntilIncluding(ClassHelper::kStartPosition);
|
||||
klass.set_token_pos(class_helper.start_position_);
|
||||
}
|
||||
|
||||
class_helper.ReadUntilIncluding(ClassHelper::kFlags);
|
||||
@@ -1237,7 +1237,7 @@ void KernelLoader::FinishClassLoading(const Class& klass,
|
||||
false, // is_abstract
|
||||
constructor_helper.IsExternal(),
|
||||
false, // is_native
|
||||
*owner, constructor_helper.position_));
|
||||
*owner, constructor_helper.start_position_));
|
||||
function.set_end_token_pos(constructor_helper.end_position_);
|
||||
functions_.Add(&function);
|
||||
function.set_kernel_offset(constructor_offset);
|
||||
@@ -1449,7 +1449,7 @@ void KernelLoader::LoadProcedure(const Library& library,
|
||||
false, // is_const
|
||||
is_abstract, is_external,
|
||||
!native_name.IsNull(), // is_native
|
||||
script_class, procedure_helper.position_));
|
||||
script_class, procedure_helper.start_position_));
|
||||
function.set_has_pragma(has_pragma_annotation);
|
||||
function.set_end_token_pos(procedure_helper.end_position_);
|
||||
functions_.Add(&function);
|
||||
|
||||
@@ -7713,6 +7713,38 @@ RawString* Function::GetSource() const {
|
||||
}
|
||||
Zone* zone = Thread::Current()->zone();
|
||||
const Script& func_script = Script::Handle(zone, script());
|
||||
|
||||
if (func_script.kind() == RawScript::kKernelTag) {
|
||||
intptr_t from_line;
|
||||
intptr_t from_col;
|
||||
intptr_t to_line;
|
||||
intptr_t to_col;
|
||||
intptr_t to_length;
|
||||
func_script.GetTokenLocation(token_pos(), &from_line, &from_col);
|
||||
func_script.GetTokenLocation(end_token_pos(), &to_line, &to_col,
|
||||
&to_length);
|
||||
|
||||
if (to_length == 1) {
|
||||
// Handle special cases for end tokens of closures (where we exclude the
|
||||
// last token):
|
||||
// (1) "foo(() => null, bar);": End token is `,', but we don't print it.
|
||||
// (2) "foo(() => null);": End token is ')`, but we don't print it.
|
||||
// (3) "var foo = () => null;": End token is `;', but in this case the
|
||||
// token semicolon belongs to the assignment so we skip it.
|
||||
const String& src = String::Handle(func_script.Source());
|
||||
uint16_t end_char = src.CharAt(end_token_pos().value());
|
||||
if ((end_char == ',') || // Case 1.
|
||||
(end_char == ')') || // Case 2.
|
||||
(end_char == ';' && String::Handle(zone, name())
|
||||
.Equals("<anonymous closure>"))) { // Case 3.
|
||||
to_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return func_script.GetSnippet(from_line, from_col, to_line,
|
||||
to_col + to_length);
|
||||
}
|
||||
|
||||
const TokenStream& stream = TokenStream::Handle(zone, func_script.tokens());
|
||||
if (!func_script.HasSource()) {
|
||||
// When source is not available, avoid printing the whole token stream and
|
||||
|
||||
@@ -145,8 +145,8 @@ mirrors/load_library_test: RuntimeError
|
||||
mirrors/metadata_allowed_values_test/16: Skip # Flaky, crashes.
|
||||
mirrors/metadata_scope_test/none: RuntimeError
|
||||
mirrors/method_mirror_location_test: RuntimeError
|
||||
mirrors/method_mirror_source_line_ending_test: Crash
|
||||
mirrors/method_mirror_source_test: Crash
|
||||
mirrors/method_mirror_source_line_ending_test: RuntimeError # Issue 33478
|
||||
mirrors/method_mirror_source_test: RuntimeError # Issue 33041
|
||||
mirrors/mirrors_nsm_mismatch_test: CompileTimeError # Issue 31533
|
||||
mirrors/mirrors_nsm_test/dart2js: CompileTimeError # Issue 31533
|
||||
mirrors/mirrors_nsm_test/none: CompileTimeError # Issue 31533
|
||||
|
||||
Reference in New Issue
Block a user