Skip to content

Commit

Permalink
Find type alias self-references during linking.
Browse files Browse the repository at this point in the history
Elements are not available for FunctionType(s), and during linking
we have the whole library cycle, so can compute self-references.

R=brianwilkerson@google.com

Change-Id: I2e145c4efae77ac5dbff2782f4b3590339187c0b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/100796
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
  • Loading branch information
scheglov authored and commit-bot@chromium.org committed Apr 30, 2019
1 parent afe805f commit ea70896
Show file tree
Hide file tree
Showing 11 changed files with 216 additions and 4 deletions.
7 changes: 7 additions & 0 deletions pkg/analyzer/lib/src/dart/element/element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5625,6 +5625,13 @@ class GenericTypeAliasElementImpl extends ElementImpl
_function = function;
}

bool get hasSelfReference {
if (linkedNode != null) {
return linkedContext.getHasTypedefSelfReference(linkedNode);
}
return false;
}

@override
bool get isSimplyBounded {
if (linkedNode != null) {
Expand Down
5 changes: 5 additions & 0 deletions pkg/analyzer/lib/src/generated/error_verifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5285,6 +5285,8 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
// should be unnecessary.
FunctionTypeAliasElement typedefElement = element.enclosingElement;
parameterElements = typedefElement.typeParameters;
} else if (type is FunctionType) {
parameterElements = type.typeFormals;
} else {
// There are no other kinds of parameterized types.
throw new UnimplementedError(
Expand Down Expand Up @@ -6190,6 +6192,9 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
if (element == null) {
return false;
}
if (element is GenericTypeAliasElementImpl && element.linkedNode != null) {
return element.hasSelfReference;
}
var visitor = new _HasTypedefSelfReferenceVisitor(element.function);
element.accept(visitor);
return visitor.hasSelfReference;
Expand Down
32 changes: 32 additions & 0 deletions pkg/analyzer/lib/src/summary/format.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9403,6 +9403,13 @@ class LinkedNodeBuilder extends Object
return _variantField_27 ??= false;
}

@override
bool get typeAlias_hasSelfReference {
assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
kind == idl.LinkedNodeKind.genericTypeAlias);
return _variantField_27 ??= false;
}

set booleanLiteral_value(bool value) {
assert(kind == idl.LinkedNodeKind.booleanLiteral);
_variantField_27 = value;
Expand Down Expand Up @@ -9436,6 +9443,12 @@ class LinkedNodeBuilder extends Object
_variantField_27 = value;
}

set typeAlias_hasSelfReference(bool value) {
assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
kind == idl.LinkedNodeKind.genericTypeAlias);
_variantField_27 = value;
}

@override
LinkedNodeBuilder get catchClause_stackTraceParameter {
assert(kind == idl.LinkedNodeKind.catchClause);
Expand Down Expand Up @@ -10121,6 +10134,7 @@ class LinkedNodeBuilder extends Object
LinkedNodeBuilder functionTypeAlias_typeParameters,
int typeAlias_typedefKeyword,
int typeAlias_semicolon,
bool typeAlias_hasSelfReference,
int codeLength,
int codeOffset,
LinkedNodeBuilder namedCompilationUnitMember_name,
Expand All @@ -10134,6 +10148,7 @@ class LinkedNodeBuilder extends Object
_variantField_8 = functionTypeAlias_typeParameters,
_variantField_18 = typeAlias_typedefKeyword,
_variantField_19 = typeAlias_semicolon,
_variantField_27 = typeAlias_hasSelfReference,
_variantField_34 = codeLength,
_variantField_33 = codeOffset,
_variantField_14 = namedCompilationUnitMember_name,
Expand Down Expand Up @@ -10787,6 +10802,7 @@ class LinkedNodeBuilder extends Object
int genericTypeAlias_equals,
int typeAlias_typedefKeyword,
int typeAlias_semicolon,
bool typeAlias_hasSelfReference,
int codeLength,
int codeOffset,
LinkedNodeBuilder namedCompilationUnitMember_name,
Expand All @@ -10799,6 +10815,7 @@ class LinkedNodeBuilder extends Object
_variantField_16 = genericTypeAlias_equals,
_variantField_18 = typeAlias_typedefKeyword,
_variantField_19 = typeAlias_semicolon,
_variantField_27 = typeAlias_hasSelfReference,
_variantField_34 = codeLength,
_variantField_33 = codeOffset,
_variantField_14 = namedCompilationUnitMember_name,
Expand Down Expand Up @@ -15279,6 +15296,15 @@ class _LinkedNodeImpl extends Object
return _variantField_27;
}

@override
bool get typeAlias_hasSelfReference {
assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
kind == idl.LinkedNodeKind.genericTypeAlias);
_variantField_27 ??=
const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
return _variantField_27;
}

@override
idl.LinkedNode get catchClause_stackTraceParameter {
assert(kind == idl.LinkedNodeKind.catchClause);
Expand Down Expand Up @@ -15775,6 +15801,8 @@ abstract class _LinkedNodeMixin implements idl.LinkedNode {
_result["typeAlias_typedefKeyword"] = typeAlias_typedefKeyword;
if (typeAlias_semicolon != 0)
_result["typeAlias_semicolon"] = typeAlias_semicolon;
if (typeAlias_hasSelfReference != false)
_result["typeAlias_hasSelfReference"] = typeAlias_hasSelfReference;
if (codeLength != 0) _result["codeLength"] = codeLength;
if (codeOffset != 0) _result["codeOffset"] = codeOffset;
if (namedCompilationUnitMember_name != null)
Expand Down Expand Up @@ -16566,6 +16594,8 @@ abstract class _LinkedNodeMixin implements idl.LinkedNode {
_result["typeAlias_typedefKeyword"] = typeAlias_typedefKeyword;
if (typeAlias_semicolon != 0)
_result["typeAlias_semicolon"] = typeAlias_semicolon;
if (typeAlias_hasSelfReference != false)
_result["typeAlias_hasSelfReference"] = typeAlias_hasSelfReference;
if (codeLength != 0) _result["codeLength"] = codeLength;
if (codeOffset != 0) _result["codeOffset"] = codeOffset;
if (namedCompilationUnitMember_name != null)
Expand Down Expand Up @@ -17513,6 +17543,7 @@ abstract class _LinkedNodeMixin implements idl.LinkedNode {
"functionTypeAlias_typeParameters": functionTypeAlias_typeParameters,
"typeAlias_typedefKeyword": typeAlias_typedefKeyword,
"typeAlias_semicolon": typeAlias_semicolon,
"typeAlias_hasSelfReference": typeAlias_hasSelfReference,
"codeLength": codeLength,
"codeOffset": codeOffset,
"namedCompilationUnitMember_name": namedCompilationUnitMember_name,
Expand Down Expand Up @@ -18058,6 +18089,7 @@ abstract class _LinkedNodeMixin implements idl.LinkedNode {
"genericTypeAlias_equals": genericTypeAlias_equals,
"typeAlias_typedefKeyword": typeAlias_typedefKeyword,
"typeAlias_semicolon": typeAlias_semicolon,
"typeAlias_hasSelfReference": typeAlias_hasSelfReference,
"codeLength": codeLength,
"codeOffset": codeOffset,
"namedCompilationUnitMember_name": namedCompilationUnitMember_name,
Expand Down
6 changes: 6 additions & 0 deletions pkg/analyzer/lib/src/summary/idl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2247,6 +2247,12 @@ abstract class LinkedNode extends base.SummaryClass {
@VariantId(16, variant: LinkedNodeKind.tryStatement)
int get tryStatement_tryKeyword;

@VariantId(27, variantList: [
LinkedNodeKind.functionTypeAlias,
LinkedNodeKind.genericTypeAlias,
])
bool get typeAlias_hasSelfReference;

@VariantId(19, variantList: [
LinkedNodeKind.classTypeAlias,
LinkedNodeKind.functionTypeAlias,
Expand Down
8 changes: 8 additions & 0 deletions pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,10 @@ class AstBinaryReader {
_getToken(data.typeAlias_semicolon),
);
LazyFunctionTypeAlias.setData(node, data);
LazyFunctionTypeAlias.setHasSelfReference(
node,
data.typeAlias_hasSelfReference,
);
return node;
}

Expand Down Expand Up @@ -679,6 +683,10 @@ class AstBinaryReader {
_getToken(data.typeAlias_semicolon),
);
LazyGenericTypeAlias.setData(node, data);
LazyGenericTypeAlias.setHasSelfReference(
node,
data.typeAlias_hasSelfReference,
);
return node;
}

Expand Down
4 changes: 4 additions & 0 deletions pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,8 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
functionTypeAlias_formalParameters: node.parameters.accept(this),
functionTypeAlias_returnType: node.returnType?.accept(this),
functionTypeAlias_typeParameters: node.typeParameters?.accept(this),
typeAlias_hasSelfReference:
LazyFunctionTypeAlias.getHasSelfReference(node),
);
_storeTypeAlias(builder, node);
_writeActualReturnType(builder, node);
Expand Down Expand Up @@ -652,6 +654,8 @@ class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
genericTypeAlias_equals: _getToken(node.equals),
genericTypeAlias_functionType: node.functionType.accept(this),
genericTypeAlias_typeParameters: node.typeParameters?.accept(this),
typeAlias_hasSelfReference:
LazyGenericTypeAlias.getHasSelfReference(node),
);
_storeTypeAlias(builder, node);
_storeIsSimpleBounded(builder, node);
Expand Down
18 changes: 18 additions & 0 deletions pkg/analyzer/lib/src/summary2/lazy_ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,7 @@ class LazyFunctionExpression {

class LazyFunctionTypeAlias {
static const _key = 'lazyAst';
static const _hasSelfReferenceKey = 'lazyAst_hasSelfReferenceKey';

final LinkedNode data;

Expand All @@ -858,6 +859,10 @@ class LazyFunctionTypeAlias {
return node.getProperty(_key);
}

static bool getHasSelfReference(FunctionTypeAlias node) {
return node.getProperty(_hasSelfReferenceKey);
}

static DartType getReturnType(
AstBinaryReader reader,
FunctionTypeAlias node,
Expand Down Expand Up @@ -931,6 +936,10 @@ class LazyFunctionTypeAlias {
node.setProperty(_key, LazyFunctionTypeAlias(data));
LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
}

static void setHasSelfReference(FunctionTypeAlias node, bool value) {
node.setProperty(_hasSelfReferenceKey, value);
}
}

class LazyGenericFunctionType {
Expand Down Expand Up @@ -996,6 +1005,7 @@ class LazyGenericFunctionType {

class LazyGenericTypeAlias {
static const _key = 'lazyAst';
static const _hasSelfReferenceKey = 'lazyAst_hasSelfReferenceKey';

final LinkedNode data;

Expand All @@ -1009,6 +1019,10 @@ class LazyGenericTypeAlias {
return node.getProperty(_key);
}

static bool getHasSelfReference(GenericTypeAlias node) {
return node.getProperty(_hasSelfReferenceKey);
}

static void readDocumentationComment(
AstBinaryReader reader,
GenericTypeAlias node,
Expand Down Expand Up @@ -1054,6 +1068,10 @@ class LazyGenericTypeAlias {
node.setProperty(_key, LazyGenericTypeAlias(data));
LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
}

static void setHasSelfReference(GenericTypeAlias node, bool value) {
node.setProperty(_hasSelfReferenceKey, value);
}
}

class LazyMethodDeclaration {
Expand Down
2 changes: 2 additions & 0 deletions pkg/analyzer/lib/src/summary2/link.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import 'package:analyzer/src/summary2/reference.dart';
import 'package:analyzer/src/summary2/simply_bounded.dart';
import 'package:analyzer/src/summary2/tokens_writer.dart';
import 'package:analyzer/src/summary2/top_level_inference.dart';
import 'package:analyzer/src/summary2/type_alias.dart';
import 'package:analyzer/src/summary2/types_builder.dart';

LinkResult link(
Expand Down Expand Up @@ -120,6 +121,7 @@ class Linker {
_addSyntheticConstructors();
_createTypeSystem();
_resolveTypes();
TypeAliasSelfReferenceFinder().perform(this);
_createLoadLibraryFunctions();
_performTopLevelInference();
_resolveConstructors();
Expand Down
9 changes: 9 additions & 0 deletions pkg/analyzer/lib/src/summary2/linked_unit_context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,15 @@ class LinkedUnitContext {
return node.functionType;
}

bool getHasTypedefSelfReference(AstNode node) {
if (node is FunctionTypeAlias) {
return LazyFunctionTypeAlias.getHasSelfReference(node);
} else if (node is GenericTypeAlias) {
return LazyGenericTypeAlias.getHasSelfReference(node);
}
return false;
}

ImplementsClause getImplementsClause(AstNode node) {
if (node is ClassDeclaration) {
LazyClassDeclaration.readImplementsClause(_astReader, node);
Expand Down
Loading

0 comments on commit ea70896

Please sign in to comment.