Skip to content

Commit

Permalink
[kernel] Add field for instantiate-to-bounds algorithm in TypeParameter.
Browse files Browse the repository at this point in the history
Change-Id: Idd1859b378080f01dc5d5078ee0960021c1689b6
Reviewed-on: https://dart-review.googlesource.com/48424
Reviewed-by: Régis Crelier <[email protected]>
Reviewed-by: Dmitry Stefantsov <[email protected]>
  • Loading branch information
sjindel-google committed Mar 27, 2018
1 parent bc75856 commit 70f4553
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 22 deletions.
1 change: 1 addition & 0 deletions pkg/kernel/binary.md
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,7 @@ type TypeParameter {
List<Expression> annotations;
StringReference name; // Cosmetic, may be empty, not unique.
DartType bound; // 'dynamic' if no explicit bound was given.
Option<DartType> defaultType; // type used when the parameter is not passed
}

```
7 changes: 7 additions & 0 deletions pkg/kernel/lib/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5220,6 +5220,13 @@ class TypeParameter extends TreeNode {
/// be set to the root class for type parameters without an explicit bound.
DartType bound;

/// The default value of the type variable. It is used to provide the
/// corresponding missing type argument in type annotations and as the
/// fall-back type value in type inference at compile time. At run time,
/// [defaultType] is used by the backends in place of the missing type
/// argument of a dynamic invocation of a generic function.
DartType defaultType;

TypeParameter([this.name, this.bound]);

// Must match serialized bit positions.
Expand Down
1 change: 1 addition & 0 deletions pkg/kernel/lib/binary/ast_from_binary.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1750,6 +1750,7 @@ class BinaryBuilder {
node.annotations = readAnnotationList(node);
node.name = readStringOrNullIfEmpty();
node.bound = readDartType();
node.defaultType = readDartTypeOption();
}

Arguments readArguments() {
Expand Down
1 change: 1 addition & 0 deletions pkg/kernel/lib/binary/ast_to_binary.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1716,6 +1716,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
writeAnnotationList(node.annotations);
writeStringReference(node.name ?? '');
writeNode(node.bound);
writeOptionalNode(node.defaultType);
}

// ================================================================
Expand Down
3 changes: 3 additions & 0 deletions pkg/kernel/lib/clone.dart
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,9 @@ class CloneVisitor implements TreeVisitor {
var newNode = new TypeParameter(node.name);
typeSubstitution[node] = new TypeParameterType(newNode);
newNode.bound = visitType(node.bound);
if (node.defaultType != null) {
newNode.defaultType = visitType(node.defaultType);
}
return newNode..flags = node.flags;
}

Expand Down
4 changes: 4 additions & 0 deletions pkg/kernel/lib/text/ast_to_text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1842,6 +1842,10 @@ class Printer extends Visitor<Null> {
writeWord(getTypeParameterName(node));
writeSpaced('extends');
writeType(node.bound);
if (node.defaultType != null) {
writeSpaced('=');
writeType(node.defaultType);
}
}

visitConstantExpression(ConstantExpression node) {
Expand Down
75 changes: 54 additions & 21 deletions runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,32 @@ void FunctionNodeHelper::ReadUntilExcluding(Field field) {
}
}

void TypeParameterHelper::ReadUntilExcluding(Field field) {
for (; next_read_ < field; ++next_read_) {
switch (next_read_) {
case kFlags:
flags_ = builder_->ReadFlags();
break;
case kAnnotations:
builder_->SkipListOfExpressions(); // read annotations.
break;
case kName:
name_index_ = builder_->ReadStringReference(); // read name index.
break;
case kBound:
builder_->SkipDartType();
break;
case kDefaultType:
if (builder_->ReadTag() == kSomething) {
builder_->SkipDartType();
}
break;
case kEnd:
return;
}
}
}

void VariableDeclarationHelper::ReadUntilExcluding(Field field) {
if (field <= next_read_) return;

Expand Down Expand Up @@ -1189,10 +1215,14 @@ void StreamingScopeBuilder::VisitFunctionNode() {
intptr_t list_length =
builder_->ReadListLength(); // read type_parameters list length.
for (intptr_t i = 0; i < list_length; ++i) {
builder_->ReadFlags(); // read flags.
builder_->SkipListOfExpressions(); // read annotations.
builder_->SkipStringReference(); // read ith name index.
TypeParameterHelper helper(builder_);
helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kBound);
VisitDartType(); // read ith bound.
helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kDefaultType);
if (builder_->ReadTag() == kSomething) {
VisitDartType(); // read ith default type.
}
helper.Finish();
}
function_node_helper.SetJustRead(FunctionNodeHelper::kTypeParameters);

Expand Down Expand Up @@ -1977,10 +2007,14 @@ void StreamingScopeBuilder::VisitFunctionType(bool simple) {
intptr_t list_length =
builder_->ReadListLength(); // read type_parameters list length.
for (int i = 0; i < list_length; ++i) {
builder_->SkipFlags(); // read flags.
builder_->SkipListOfExpressions(); // read annotations.
builder_->SkipStringReference(); // read string index (name).
VisitDartType(); // read dart type.
TypeParameterHelper helper(builder_);
helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kBound);
VisitDartType(); // read bound.
helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kDefaultType);
if (builder_->ReadTag() == kSomething) {
VisitDartType(); // read default type.
}
helper.Finish();
}
builder_->ReadUInt(); // read required parameter count.
builder_->ReadUInt(); // read total parameter count.
Expand Down Expand Up @@ -4569,10 +4603,11 @@ Fragment StreamingFlowGraphBuilder::BuildArgumentTypeChecks(
}
TypeParameter& forwarding_param = TypeParameter::Handle(Z);
for (intptr_t i = 0; i < num_type_params; ++i) {
ReadFlags(); // skip flags
SkipListOfExpressions(); // skip annotations
String& name = H.DartSymbolObfuscate(ReadStringReference()); // read name
TypeParameterHelper helper(this);
helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kBound);
String& name = H.DartSymbolObfuscate(helper.name_index_);
AbstractType& bound = T.BuildType(); // read bound
helper.Finish();

if (forwarding_target != NULL) {
forwarding_param ^= forwarding_params.TypeAt(i);
Expand Down Expand Up @@ -5488,10 +5523,8 @@ void StreamingFlowGraphBuilder::SkipListOfVariableDeclarations() {
void StreamingFlowGraphBuilder::SkipTypeParametersList() {
intptr_t list_length = ReadListLength(); // read list length.
for (intptr_t i = 0; i < list_length; ++i) {
SkipFlags(); // read ith flags.
SkipListOfExpressions(); // read annotations.
SkipStringReference(); // read ith name index.
SkipDartType(); // read ith bound.
TypeParameterHelper helper(this);
helper.Finish();
}
}

Expand Down Expand Up @@ -9603,15 +9636,14 @@ void StreamingFlowGraphBuilder::LoadAndSetupTypeParameters(
{
AlternativeReadingScope alt(reader_);
for (intptr_t i = 0; i < type_parameter_count; i++) {
SkipFlags();
SkipListOfExpressions(); // read annotations.
TypeParameterHelper helper(this);
helper.Finish();
parameter = TypeParameter::New(
set_on_class ? *active_class->klass : Class::Handle(Z),
parameterized_function, i,
H.DartSymbolObfuscate(ReadStringReference()), // read ith name index.
H.DartSymbolObfuscate(helper.name_index_), // read ith name index.
null_bound, TokenPosition::kNoSource);
type_parameters.SetTypeAt(i, parameter);
SkipDartType(); // read guard.
}
}

Expand All @@ -9629,9 +9661,8 @@ void StreamingFlowGraphBuilder::LoadAndSetupTypeParameters(

// Step b) Fill in the bounds of all [TypeParameter]s.
for (intptr_t i = 0; i < type_parameter_count; i++) {
SkipFlags();
SkipListOfExpressions(); // read annotations.
SkipStringReference(); // read ith name index.
TypeParameterHelper helper(this);
helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kBound);

// TODO(github.com/dart-lang/kernel/issues/42): This should be handled
// by the frontend.
Expand All @@ -9648,6 +9679,8 @@ void StreamingFlowGraphBuilder::LoadAndSetupTypeParameters(
}
parameter.set_bound(bound);
}

helper.Finish();
}
}

Expand Down
43 changes: 42 additions & 1 deletion runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,51 @@ class FunctionNodeHelper {
intptr_t next_read_;
};

struct TypeParameterHelper {
class TypeParameterHelper {
public:
enum Field {
kStart, // tag.
kFlags,
kAnnotations,
kName,
kBound,
kDefaultType,
kEnd,
};

enum Flag {
kIsGenericCovariantImpl = 1 << 0,
kIsGenericCovariantInterface = 1 << 1
};

explicit TypeParameterHelper(StreamingFlowGraphBuilder* builder) {
builder_ = builder;
next_read_ = kStart;
}

void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
}

void ReadUntilExcluding(Field field);

void SetNext(Field field) { next_read_ = field; }
void SetJustRead(Field field) { next_read_ = field + 1; }

void ReadUntilExcludingAndSetJustRead(Field field) {
ReadUntilExcluding(field);
SetJustRead(field);
}

void Finish() { ReadUntilExcluding(kEnd); }

TokenPosition position_;
uint8_t flags_;
StringIndex name_index_;

private:
StreamingFlowGraphBuilder* builder_;
intptr_t next_read_;
};

// Helper class that reads a kernel VariableDeclaration from binary.
Expand Down Expand Up @@ -1434,6 +1474,7 @@ class StreamingFlowGraphBuilder {
friend class StreamingDartTypeTranslator;
friend class StreamingScopeBuilder;
friend class VariableDeclarationHelper;
friend class TypeParameterHelper;
};

class AlternativeScriptScope {
Expand Down

0 comments on commit 70f4553

Please sign in to comment.