Skip to content

Commit

Permalink
Preserve type aliases for records in output (#3340)
Browse files Browse the repository at this point in the history
* Test records in the experiments package

* Refactor with tests

* Rebuild after pub upgrade

* Move constructor_tearoffs to the main test package so we can run tests on 2.19.

* Update pubspec.

* Fix up test package for new language version.

* Fix references to remove new

* Review comments
  • Loading branch information
jcollins-g authored Feb 16, 2023
1 parent 96e6190 commit dba6f94
Show file tree
Hide file tree
Showing 18 changed files with 540 additions and 463 deletions.
440 changes: 220 additions & 220 deletions lib/resources/docs.dart.js

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions lib/resources/docs.dart.js.map

Large diffs are not rendered by default.

109 changes: 61 additions & 48 deletions lib/src/element_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,54 +40,14 @@ abstract class ElementType extends Privacy

factory ElementType._from(
DartType f, Library library, PackageGraph packageGraph) {
if (f is RecordType) {
return RecordElementType(f, library, packageGraph);
}
var fElement = DartTypeExtension(f).element;
if (fElement == null ||
fElement.kind == ElementKind.DYNAMIC ||
fElement.kind == ElementKind.NEVER) {
// [UndefinedElementType]s.
if (f is FunctionType) {
if (f.alias?.element != null) {
return AliasedFunctionTypeElementType(f, library, packageGraph);
}
return FunctionTypeElementType(f, library, packageGraph);
}
return UndefinedElementType(f, library, packageGraph);
}
// [DefinedElementType]s.
var element = packageGraph.modelBuilder.fromElement(fElement);
// `TypeAliasElement.alias.element` has different implications.
// In that case it is an actual type alias of some kind (generic or
// otherwise). Here however `alias.element` signals that this is a type
// referring to an alias.
if (f is! TypeAliasElement && f.alias?.element != null) {
return AliasedElementType(
f as ParameterizedType, library, packageGraph, element);
}
assert(f is ParameterizedType || f is TypeParameterType);
// TODO(jcollins-g): strip out all the cruft that's accumulated
// here for non-generic type aliases.
var isGenericTypeAlias = f.alias?.element != null && f is! InterfaceType;
if (f is FunctionType) {
assert(f is ParameterizedType);
// And finally, delete this case and its associated class
// after https://dart-review.googlesource.com/c/sdk/+/201520
// is in all published versions of analyzer this version of dartdoc
// is compatible with.
return CallableElementType(f, library, packageGraph, element);
return UndefinedElementType._from(f, library, packageGraph);
}
if (isGenericTypeAlias) {
return GenericTypeAliasElementType(
f as TypeParameterType, library, packageGraph, element);
}
if (f is TypeParameterType) {
return TypeParameterElementType(f, library, packageGraph, element);
}
assert(f is ParameterizedType);
return ParameterizedElementType(
f as ParameterizedType, library, packageGraph, element);
var modelElement = packageGraph.modelBuilder.fromElement(fElement);
return DefinedElementType._from(f, modelElement, library, packageGraph);
}

/// The element of [type].
Expand Down Expand Up @@ -118,6 +78,24 @@ abstract class ElementType extends Privacy
class UndefinedElementType extends ElementType {
UndefinedElementType(super.f, super.library, super.packageGraph);

factory UndefinedElementType._from(
DartType f, Library library, PackageGraph packageGraph) {
// [UndefinedElementType]s.
if (f.alias?.element != null) {
if (f is FunctionType) {
return AliasedUndefinedFunctionElementType(f, library, packageGraph);
}
return AliasedUndefinedElementType(f, library, packageGraph);
}
if (f is RecordType) {
return RecordElementType(f, library, packageGraph);
}
if (f is FunctionType) {
return FunctionTypeElementType(f, library, packageGraph);
}
return UndefinedElementType(f, library, packageGraph);
}

@override
bool get isPublic => true;

Expand Down Expand Up @@ -196,16 +174,22 @@ class RecordElementType extends UndefinedElementType with Rendered {
RecordType get type => super.type as RecordType;
}

class AliasedFunctionTypeElementType extends FunctionTypeElementType
with Aliased {
AliasedFunctionTypeElementType(super.f, super.library, super.packageGraph) {
class AliasedUndefinedFunctionElementType extends AliasedUndefinedElementType
with Callable {
AliasedUndefinedFunctionElementType(
super.f, super.library, super.packageGraph);
}

class AliasedUndefinedElementType extends UndefinedElementType
with Aliased, Rendered {
AliasedUndefinedElementType(super.f, super.library, super.packageGraph) {
assert(type.alias?.element != null);
assert(type.alias?.typeArguments != null);
}

@override
ElementTypeRenderer<AliasedFunctionTypeElementType> get _renderer =>
packageGraph.rendererFactory.aliasedFunctionTypeElementTypeRenderer;
ElementTypeRenderer get _renderer =>
packageGraph.rendererFactory.aliasedUndefinedElementTypeRenderer;
}

class ParameterizedElementType extends DefinedElementType with Rendered {
Expand Down Expand Up @@ -284,6 +268,35 @@ abstract class DefinedElementType extends ElementType {
DefinedElementType(
super.type, super.library, super.packageGraph, this.modelElement);

factory DefinedElementType._from(DartType f, ModelElement modelElement,
Library library, PackageGraph packageGraph) {
// `TypeAliasElement.alias.element` has different implications.
// In that case it is an actual type alias of some kind (generic or
// otherwise). Here however `alias.element` signals that this is a type
// referring to an alias.
if (f is! TypeAliasElement && f.alias?.element != null) {
return AliasedElementType(
f as ParameterizedType, library, packageGraph, modelElement);
}
assert(f is ParameterizedType || f is TypeParameterType);
assert(f is! FunctionType,
'detected DefinedElementType for FunctionType: analyzer version too old?');
// TODO(jcollins-g): strip out all the cruft that's accumulated
// here for non-generic type aliases.
var isGenericTypeAlias = f.alias?.element != null && f is! InterfaceType;
if (isGenericTypeAlias) {
assert(false);
return GenericTypeAliasElementType(
f as TypeParameterType, library, packageGraph, modelElement);
}
if (f is TypeParameterType) {
return TypeParameterElementType(f, library, packageGraph, modelElement);
}
assert(f is ParameterizedType);
return ParameterizedElementType(
f as ParameterizedType, library, packageGraph, modelElement);
}

Element get element => modelElement.element;

@override
Expand Down
16 changes: 16 additions & 0 deletions lib/src/generator/templates.runtime_renderers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15627,9 +15627,15 @@ const _invisibleGetters = {
'hasNonFinalField',
'hashCode',
'isAbstract',
'isBase',
'isDartCoreEnum',
'isDartCoreObject',
'isExhaustive',
'isFinal',
'isInterface',
'isMixinApplication',
'isMixinClass',
'isSealed',
'isValidMixin',
'runtimeType',
'superclassConstraints'
Expand Down Expand Up @@ -15799,6 +15805,7 @@ const _invisibleGetters = {
'hasOptionalTypeArgs',
'hasOverride',
'hasProtected',
'hasReopen',
'hasRequired',
'hasSealed',
'hasUseResult',
Expand Down Expand Up @@ -15843,6 +15850,7 @@ const _invisibleGetters = {
'isOverride',
'isProtected',
'isProxy',
'isReopen',
'isRequired',
'isSealed',
'isTarget',
Expand Down Expand Up @@ -15877,6 +15885,7 @@ const _invisibleGetters = {
'hasOptionalTypeArgs',
'hasOverride',
'hasProtected',
'hasReopen',
'hasRequired',
'hasSealed',
'hasUseResult',
Expand Down Expand Up @@ -16126,6 +16135,7 @@ const _invisibleGetters = {
'hasOptionalTypeArgs',
'hasOverride',
'hasProtected',
'hasReopen',
'hasRequired',
'hasSealed',
'hasUseResult',
Expand Down Expand Up @@ -16155,6 +16165,11 @@ const _invisibleGetters = {
'MixinElement': {
'augmented',
'hashCode',
'isBase',
'isExhaustive',
'isFinal',
'isInterface',
'isSealed',
'runtimeType',
'superclassConstraints'
},
Expand Down Expand Up @@ -16279,6 +16294,7 @@ const _invisibleGetters = {
'hasOptionalTypeArgs',
'hasOverride',
'hasProtected',
'hasReopen',
'hasRequired',
'hasSealed',
'hasUseResult',
Expand Down
20 changes: 10 additions & 10 deletions lib/src/render/element_type_renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -138,20 +138,20 @@ class RecordElementTypeRendererHtml
}
}

class AliasedFunctionTypeElementTypeRendererHtml
extends ElementTypeRendererHtml<AliasedFunctionTypeElementType> {
const AliasedFunctionTypeElementTypeRendererHtml();
class AliasedUndefinedElementTypeRendererHtml
extends ElementTypeRendererHtml<AliasedUndefinedElementType> {
const AliasedUndefinedElementTypeRendererHtml();

@override
String renderLinkedName(AliasedFunctionTypeElementType elementType) =>
String renderLinkedName(AliasedUndefinedElementType elementType) =>
_renderLinkedName(
elementType,
elementType.aliasElement.linkedName,
elementType.aliasArguments,
);

@override
String renderNameWithGenerics(AliasedFunctionTypeElementType elementType) =>
String renderNameWithGenerics(AliasedUndefinedElementType elementType) =>
_renderNameWithGenerics(
elementType,
elementType.aliasElement.name,
Expand Down Expand Up @@ -340,20 +340,20 @@ class AliasedElementTypeRendererMd
);
}

class AliasedFunctionTypeElementTypeRendererMd
extends ElementTypeRendererMd<AliasedFunctionTypeElementType> {
const AliasedFunctionTypeElementTypeRendererMd();
class AliasedUndefinedElementTypeRendererMd
extends ElementTypeRendererMd<AliasedUndefinedElementType> {
const AliasedUndefinedElementTypeRendererMd();

@override
String renderLinkedName(AliasedFunctionTypeElementType elementType) =>
String renderLinkedName(AliasedUndefinedElementType elementType) =>
_renderLinkedName(
elementType,
elementType.aliasElement.linkedName,
elementType.aliasArguments,
);

@override
String renderNameWithGenerics(AliasedFunctionTypeElementType elementType) =>
String renderNameWithGenerics(AliasedUndefinedElementType elementType) =>
_renderNameWithGenerics(
elementType,
elementType.aliasElement.name,
Expand Down
16 changes: 8 additions & 8 deletions lib/src/render/renderer_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ abstract class RendererFactory {

ElementTypeRenderer<AliasedElementType> get aliasedElementTypeRenderer;

ElementTypeRenderer<AliasedFunctionTypeElementType>
get aliasedFunctionTypeElementTypeRenderer;
ElementTypeRenderer<AliasedUndefinedElementType>
get aliasedUndefinedElementTypeRenderer;

ElementTypeRenderer<CallableElementType> get callableElementTypeRenderer;

Expand Down Expand Up @@ -140,9 +140,9 @@ class HtmlRenderFactory extends RendererFactory {
FeatureRenderer get featureRenderer => const FeatureRendererHtml();

@override
ElementTypeRenderer<AliasedFunctionTypeElementType>
get aliasedFunctionTypeElementTypeRenderer =>
const AliasedFunctionTypeElementTypeRendererHtml();
ElementTypeRenderer<AliasedUndefinedElementType>
get aliasedUndefinedElementTypeRenderer =>
const AliasedUndefinedElementTypeRendererHtml();
}

class MdRenderFactory extends RendererFactory {
Expand Down Expand Up @@ -213,7 +213,7 @@ class MdRenderFactory extends RendererFactory {
FeatureRenderer get featureRenderer => const FeatureRendererMd();

@override
ElementTypeRenderer<AliasedFunctionTypeElementType>
get aliasedFunctionTypeElementTypeRenderer =>
const AliasedFunctionTypeElementTypeRendererMd();
ElementTypeRenderer<AliasedUndefinedElementType>
get aliasedUndefinedElementTypeRenderer =>
const AliasedUndefinedElementTypeRendererMd();
}
Loading

0 comments on commit dba6f94

Please sign in to comment.