Skip to content

Enable using summary2 for analysis #2026

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Sep 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 146 additions & 52 deletions lib/src/element_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,31 @@
/// The models used to represent Dart code.
library dartdoc.element_type;

import 'dart:collection';

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:dartdoc/src/model.dart';
import 'package:dartdoc/src/model_utils.dart';

/// Base class representing a type in Dartdoc. It wraps a [DartType], and
/// may link to a [ModelElement].
abstract class ElementType extends Privacy {
final DartType _type;
final PackageGraph packageGraph;
final DefinedElementType returnedFrom;
final ElementType returnedFrom;
final Library library;

ElementType(this._type, this.packageGraph, this.returnedFrom);
ElementType(this._type, this.library, this.packageGraph, this.returnedFrom);

factory ElementType.from(DartType f, PackageGraph packageGraph,
factory ElementType.from(
DartType f, Library library, PackageGraph packageGraph,
[ElementType returnedFrom]) {
if (f.element == null || f.element.kind == ElementKind.DYNAMIC) {
return UndefinedElementType(f, packageGraph, returnedFrom);
if (f is FunctionType) {
return FunctionTypeElementType(f, library, packageGraph, returnedFrom);
}
return UndefinedElementType(f, library, packageGraph, returnedFrom);
} else {
ModelElement element = ModelElement.fromElement(f.element, packageGraph);
assert(f is ParameterizedType || f is TypeParameterType);
Expand All @@ -32,29 +40,32 @@ abstract class ElementType extends Privacy {
if (isGenericTypeAlias) {
assert(element is! ModelFunctionAnonymous);
return CallableGenericTypeAliasElementType(
f, packageGraph, element, returnedFrom);
f, library, packageGraph, element, returnedFrom);
} else {
if (element is ModelFunctionAnonymous) {
return CallableAnonymousElementType(
f, packageGraph, element, returnedFrom);
f, library, packageGraph, element, returnedFrom);
} else {
assert(element is! ModelFunctionAnonymous);
return CallableElementType(f, packageGraph, element, returnedFrom);
return CallableElementType(
f, library, packageGraph, element, returnedFrom);
}
}
} else if (isGenericTypeAlias) {
assert(f is TypeParameterType);
assert(element is! ModelFunctionAnonymous);
return GenericTypeAliasElementType(
f, packageGraph, element, returnedFrom);
f, library, packageGraph, element, returnedFrom);
}
if (f is TypeParameterType) {
assert(element is! ModelFunctionAnonymous);
return TypeParameterElementType(f, packageGraph, element, returnedFrom);
return TypeParameterElementType(
f, library, packageGraph, element, returnedFrom);
}
assert(f is ParameterizedType);
assert(element is! ModelFunctionAnonymous);
return ParameterizedElementType(f, packageGraph, element, returnedFrom);
return ParameterizedElementType(
f, library, packageGraph, element, returnedFrom);
}
}

Expand Down Expand Up @@ -83,31 +94,104 @@ abstract class ElementType extends Privacy {
/// An [ElementType] that isn't pinned to an Element (or one that is, but whose
/// element is irrelevant).
class UndefinedElementType extends ElementType {
UndefinedElementType(
DartType f, PackageGraph packageGraph, ElementType returnedFrom)
: super(f, packageGraph, returnedFrom);
UndefinedElementType(DartType f, Library library, PackageGraph packageGraph,
ElementType returnedFrom)
: super(f, library, packageGraph, returnedFrom);

String _linkedName;

@override
bool get isPublic => true;

@override
String get nameWithGenerics => name;

/// dynamic and void are not allowed to have parameterized types.
@override
String get linkedName {
if (type.isDynamic &&
returnedFrom != null &&
returnedFrom.element.isAsynchronous) return 'Future';
(returnedFrom is DefinedElementType &&
(returnedFrom as DefinedElementType).element.isAsynchronous)) {
return 'Future';
}
return name;
}

@override
String get nameWithGenerics => name;
String get name => type.name ?? '';
}

/// A FunctionType that does not have an underpinning Element.
class FunctionTypeElementType extends UndefinedElementType {
FunctionTypeElementType(DartType f, Library library,
PackageGraph packageGraph, ElementType returnedFrom)
: super(f, library, packageGraph, returnedFrom);

@override
List<Parameter> get parameters {
List<ParameterElement> params = (type as FunctionType).parameters;
return UnmodifiableListView<Parameter>(params
.map((p) => ModelElement.from(p, library, packageGraph) as Parameter)
.toList());
}

ElementType get returnType => ElementType.from(
(type as FunctionType).returnType, library, packageGraph, this);

@override
String get linkedName {
if (_linkedName == null) {
StringBuffer buf = StringBuffer();
buf.write('${returnType.linkedName} ');
buf.write('${nameWithGenerics}');
buf.write('<span class="signature">');
buf.write('(${linkedParams(parameters)})');
buf.write('</span>');
_linkedName = buf.toString();
}
return _linkedName;
}

@override
String createLinkedReturnTypeName() => returnType.linkedName;

String _nameWithGenerics;

@override
String get nameWithGenerics {
if (_nameWithGenerics == null) {
StringBuffer buf = StringBuffer();
buf.write(name);
if ((type as FunctionType).typeFormals.isNotEmpty) {
if (!typeFormals.every((t) => t.name == 'dynamic')) {
buf.write('&lt;<wbr><span class="type-parameter">');
buf.writeAll(typeFormals.map((t) => t.name),
'</span>, <span class="type-parameter">');
buf.write('</span>&gt;');
}
}
_nameWithGenerics = buf.toString();
}
return _nameWithGenerics;
}

List<TypeParameter> get typeFormals {
List<TypeParameterElement> typeFormals = (type as FunctionType).typeFormals;
return UnmodifiableListView<TypeParameter>(typeFormals
.map(
(p) => ModelElement.from(p, library, packageGraph) as TypeParameter)
.toList());
}

@override
String get name => 'Function';
}

class ParameterizedElementType extends DefinedElementType {
ParameterizedElementType(ParameterizedType type, PackageGraph packageGraph,
ModelElement element, ElementType returnedFrom)
: super(type, packageGraph, element, returnedFrom);
ParameterizedElementType(ParameterizedType type, Library library,
PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
: super(type, library, packageGraph, element, returnedFrom);

String _linkedName;
@override
Expand Down Expand Up @@ -154,9 +238,9 @@ class ParameterizedElementType extends DefinedElementType {
}

class TypeParameterElementType extends DefinedElementType {
TypeParameterElementType(TypeParameterType type, PackageGraph packageGraph,
ModelElement element, ElementType returnedFrom)
: super(type, packageGraph, element, returnedFrom);
TypeParameterElementType(TypeParameterType type, Library library,
PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
: super(type, library, packageGraph, element, returnedFrom);

@override
String get linkedName => name;
Expand All @@ -175,9 +259,9 @@ class TypeParameterElementType extends DefinedElementType {
abstract class DefinedElementType extends ElementType {
final ModelElement _element;

DefinedElementType(DartType type, PackageGraph packageGraph, this._element,
ElementType returnedFrom)
: super(type, packageGraph, returnedFrom);
DefinedElementType(DartType type, Library library, PackageGraph packageGraph,
this._element, ElementType returnedFrom)
: super(type, library, packageGraph, returnedFrom);

ModelElement get element {
assert(_element != null);
Expand Down Expand Up @@ -208,7 +292,7 @@ abstract class DefinedElementType extends ElementType {
ElementType _returnType;
ElementType get returnType {
if (_returnType == null) {
_returnType = ElementType.from(type, packageGraph, this);
_returnType = ElementType.from(type, library, packageGraph, this);
}
return _returnType;
}
Expand All @@ -221,7 +305,7 @@ abstract class DefinedElementType extends ElementType {
if (_typeArguments == null) {
_typeArguments = (type as ParameterizedType)
.typeArguments
.map((f) => ElementType.from(f, packageGraph))
.map((f) => ElementType.from(f, library, packageGraph))
.toList();
}
return _typeArguments;
Expand All @@ -238,7 +322,8 @@ abstract class CallableElementTypeMixin implements ParameterizedElementType {
@override
ElementType get returnType {
if (_returnType == null) {
_returnType = ElementType.from(type.returnType, packageGraph, this);
_returnType =
ElementType.from(type.returnType, library, packageGraph, this);
}
return _returnType;
}
Expand All @@ -252,19 +337,28 @@ abstract class CallableElementTypeMixin implements ParameterizedElementType {
Iterable<ElementType> get typeArguments {
if (_typeArguments == null) {
Iterable<DartType> dartTypeArguments;
if (type.typeFormals.isEmpty &&
element is! ModelFunctionAnonymous &&
returnedFrom?.element is! ModelFunctionAnonymous) {
dartTypeArguments = type.typeArguments;
} else if (returnedFrom != null &&
returnedFrom.type.element is GenericFunctionTypeElement) {
_typeArguments = returnedFrom.typeArguments;
if (returnedFrom is FunctionTypeElementType) {
if (type.typeFormals.isEmpty) {
dartTypeArguments = type.typeArguments;
} else {
dartTypeArguments = type.typeFormals.map((f) => f.type);
}
} else {
dartTypeArguments = type.typeFormals.map((f) => f.type);
DefinedElementType elementType = returnedFrom as DefinedElementType;
if (type.typeFormals.isEmpty &&
element is! ModelFunctionAnonymous &&
elementType?.element is! ModelFunctionAnonymous) {
dartTypeArguments = type.typeArguments;
} else if (returnedFrom != null &&
returnedFrom.type.element is GenericFunctionTypeElement) {
_typeArguments = (returnedFrom as DefinedElementType).typeArguments;
} else {
dartTypeArguments = type.typeFormals.map((f) => f.type);
}
}
if (dartTypeArguments != null) {
_typeArguments = dartTypeArguments
.map((f) => ElementType.from(f, packageGraph))
.map((f) => ElementType.from(f, library, packageGraph))
.toList();
}
}
Expand All @@ -276,31 +370,31 @@ abstract class CallableElementTypeMixin implements ParameterizedElementType {
/// function syntax.
class CallableElementType extends ParameterizedElementType
with CallableElementTypeMixin {
CallableElementType(FunctionType t, PackageGraph packageGraph,
ModelElement element, ElementType returnedFrom)
: super(t, packageGraph, element, returnedFrom);
CallableElementType(FunctionType t, Library library,
PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
: super(t, library, packageGraph, element, returnedFrom);

@override
String get linkedName {
if (name != null && name.isNotEmpty) return super.linkedName;
return '${nameWithGenerics}(${element.linkedParams(showNames: false).trim()}) → ${returnType.linkedName}';
return '${nameWithGenerics}(${linkedParams(element.parameters, showNames: false).trim()}) → ${returnType.linkedName}';
}
}

/// This is an anonymous function using the generic function syntax (declared
/// literally with "Function").
class CallableAnonymousElementType extends CallableElementType {
CallableAnonymousElementType(FunctionType t, PackageGraph packageGraph,
ModelElement element, ElementType returnedFrom)
: super(t, packageGraph, element, returnedFrom);
CallableAnonymousElementType(FunctionType t, Library library,
PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
: super(t, library, packageGraph, element, returnedFrom);
@override
String get name => 'Function';

@override
String get linkedName {
if (_linkedName == null) {
_linkedName =
'${returnType.linkedName} ${super.linkedName}<span class="signature">(${element.linkedParams()})</span>';
'${returnType.linkedName} ${super.linkedName}<span class="signature">(${linkedParams(element.parameters)})</span>';
}
return _linkedName;
}
Expand All @@ -312,17 +406,17 @@ abstract class GenericTypeAliasElementTypeMixin {}
/// A non-callable type backed by a [GenericTypeAliasElement].
class GenericTypeAliasElementType extends TypeParameterElementType
with GenericTypeAliasElementTypeMixin {
GenericTypeAliasElementType(TypeParameterType t, PackageGraph packageGraph,
ModelElement element, ElementType returnedFrom)
: super(t, packageGraph, element, returnedFrom);
GenericTypeAliasElementType(TypeParameterType t, Library library,
PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
: super(t, library, packageGraph, element, returnedFrom);
}

/// A Callable generic type alias that may or may not have a name.
class CallableGenericTypeAliasElementType extends ParameterizedElementType
with CallableElementTypeMixin, GenericTypeAliasElementTypeMixin {
CallableGenericTypeAliasElementType(FunctionType t, PackageGraph packageGraph,
ModelElement element, ElementType returnedFrom)
: super(t, packageGraph, element, returnedFrom);
CallableGenericTypeAliasElementType(FunctionType t, Library library,
PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
: super(t, library, packageGraph, element, returnedFrom);

ModelElement _returnElement;
@override
Expand All @@ -337,8 +431,8 @@ class CallableGenericTypeAliasElementType extends ParameterizedElementType
@override
ElementType get returnType {
if (_returnType == null) {
_returnType =
ElementType.from(returnElement.modelType.type, packageGraph, this);
_returnType = ElementType.from(
returnElement.modelType.type, library, packageGraph, this);
}
return _returnType;
}
Expand Down
Loading