Version 1.23.0-dev.11.8
Cherry-pick d52a6a39d54fd2116aea7f2980500f92e4677e10 to dev
Cherry-pick 492eab84ece070ff262b958d0786fa42db9645df to dev
Cherry-pick e520fc2a455c16ef5e2bd798ab08a1842c08134d to dev
Cherry-pick 23f08ec04a1907e43469f080601822431128cd60 to dev
Cherry-pick e30b56ccbe36686612fc53e1c5da04905eaef969 to dev
Cherry-pick b277f1023c8a6e553603498710e757c5c7a2c8f1 to dev
Cherry-pick f0ae30dca5ada7fc18d7b0c42fc05ff9aa3a64d0 to dev
Cherry-pick 214308773419d67e9380dca38c7332dbd8496988 to dev
Cherry-pick 7696ec5f31e32939728641c28caf0d607fcbdbba to dev
Cherry-pick 5f28891e617cb109ba3e7a5849dfcb791b8ae3a7 to dev
Cherry-pick 54f845cfd2bcb36213e10ff5ea994d1cd86e9bee to dev
Cherry-pick fcac30e080955bea12a7d39467a91268ffad4b19 to dev
Cherry-pick 37aeef8d6e64435293415bf9aac06ba02b782149 to dev
diff --git a/DEPS b/DEPS
index 2fafc01..0a3f022 100644
--- a/DEPS
+++ b/DEPS
@@ -37,7 +37,7 @@
"gperftools_revision": "@02eeed29df112728564a5dde6417fa4622b57a06",
# Revisions of /third_party/* dependencies.
- "angular_analyzer_plugin_tag": "@v0.0.7",
+ "angular_analyzer_plugin_tag": "@v0.0.8",
"args_tag": "@0.13.7",
"async_tag": "@1.13.0",
"barback-0.13.0_rev": "@34853",
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 157d8d8..3ec8098 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -72,7 +72,7 @@
/**
* The version of data format, should be incremented on every format change.
*/
- static const int DATA_VERSION = 28;
+ static const int DATA_VERSION = 29;
/**
* The number of exception contexts allowed to write. Once this field is
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
index f90698a..0079e47 100644
--- a/pkg/analyzer/lib/src/dart/element/builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -427,22 +427,6 @@
}
@override
- Object visitGenericFunctionType(GenericFunctionType node) {
- ElementHolder holder = new ElementHolder();
- _visitChildren(holder, node);
- GenericFunctionTypeElementImpl element =
- new GenericFunctionTypeElementImpl.forOffset(node.beginToken.offset);
- _setCodeRange(element, node);
- element.parameters = holder.parameters;
- element.typeParameters = holder.typeParameters;
- FunctionType type = new FunctionTypeImpl(element);
- element.type = type;
- (node as GenericFunctionTypeImpl).type = type;
- holder.validate();
- return null;
- }
-
- @override
Object visitGenericTypeAlias(GenericTypeAlias node) {
ElementHolder holder = new ElementHolder();
_visitChildren(holder, node);
@@ -1481,6 +1465,22 @@
}
@override
+ Object visitGenericFunctionType(GenericFunctionType node) {
+ ElementHolder holder = new ElementHolder();
+ _visitChildren(holder, node);
+ GenericFunctionTypeElementImpl element =
+ new GenericFunctionTypeElementImpl.forOffset(node.beginToken.offset);
+ _setCodeRange(element, node);
+ element.parameters = holder.parameters;
+ element.typeParameters = holder.typeParameters;
+ FunctionType type = new FunctionTypeImpl(element);
+ element.type = type;
+ (node as GenericFunctionTypeImpl).type = type;
+ holder.validate();
+ return null;
+ }
+
+ @override
Object visitSimpleFormalParameter(SimpleFormalParameter node) {
ParameterElementImpl parameter;
if (node.parent is! DefaultFormalParameter) {
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 57c8d14..d3432fe 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -724,7 +724,7 @@
if (_unlinkedClass != null && _interfaces == null) {
ResynthesizerContext context = enclosingUnit.resynthesizerContext;
_interfaces = _unlinkedClass.interfaces
- .map((EntityRef t) => context.resolveTypeRef(t, this))
+ .map((EntityRef t) => context.resolveTypeRef(this, t))
.where(_isClassInterfaceType)
.toList(growable: false);
}
@@ -831,7 +831,7 @@
if (_unlinkedClass != null && _mixins == null) {
ResynthesizerContext context = enclosingUnit.resynthesizerContext;
_mixins = _unlinkedClass.mixins
- .map((EntityRef t) => context.resolveTypeRef(t, this))
+ .map((EntityRef t) => context.resolveTypeRef(this, t))
.where(_isClassInterfaceType)
.toList(growable: false);
}
@@ -865,7 +865,7 @@
if (_unlinkedClass != null && _supertype == null) {
if (_unlinkedClass.supertype != null) {
DartType type = enclosingUnit.resynthesizerContext
- .resolveTypeRef(_unlinkedClass.supertype, this);
+ .resolveTypeRef(this, _unlinkedClass.supertype);
if (_isClassInterfaceType(type)) {
_supertype = type;
} else {
@@ -3879,10 +3879,10 @@
_returnType == null) {
bool isSetter =
serializedExecutable.kind == UnlinkedExecutableKind.setter;
- _returnType = enclosingUnit.resynthesizerContext.resolveLinkedType(
- serializedExecutable.inferredReturnTypeSlot, typeParameterContext);
+ _returnType = enclosingUnit.resynthesizerContext
+ .resolveLinkedType(this, serializedExecutable.inferredReturnTypeSlot);
_declaredReturnType = enclosingUnit.resynthesizerContext.resolveTypeRef(
- serializedExecutable.returnType, typeParameterContext,
+ this, serializedExecutable.returnType,
defaultVoid: isSetter && context.analysisOptions.strongMode,
declaredType: true);
}
@@ -4572,7 +4572,7 @@
@override
DartType get returnType {
return _returnType ??= enclosingUnit.resynthesizerContext
- .resolveTypeRef(_entityRef.syntheticReturnType, typeParameterContext);
+ .resolveTypeRef(this, _entityRef.syntheticReturnType);
}
@override
@@ -4736,7 +4736,7 @@
DartType get returnType {
if (_unlinkedTypedef != null && _returnType == null) {
_returnType = enclosingUnit.resynthesizerContext.resolveTypeRef(
- _unlinkedTypedef.returnType, this,
+ this, _unlinkedTypedef.returnType,
declaredType: true);
}
return _returnType;
@@ -4859,11 +4859,6 @@
EntityRef _entityRef;
/**
- * The enclosing type parameter context.
- */
- TypeParameterizedElementMixin _typeParameterContext;
-
- /**
* The declared return type of the function.
*/
DartType _returnType;
@@ -4889,13 +4884,13 @@
* Initialize from serialized information.
*/
GenericFunctionTypeElementImpl.forSerialized(
- this._entityRef, this._typeParameterContext)
- : super.forSerialized(null);
+ ElementImpl enclosingElement, this._entityRef)
+ : super.forSerialized(enclosingElement);
@override
- TypeParameterizedElementMixin get enclosingTypeParameterContext =>
- _typeParameterContext ??
- (enclosingElement as ElementImpl).typeParameterContext;
+ TypeParameterizedElementMixin get enclosingTypeParameterContext {
+ return _enclosingElement.typeParameterContext;
+ }
@override
String get identifier => '-';
@@ -4928,7 +4923,7 @@
DartType get returnType {
if (_entityRef != null && _returnType == null) {
_returnType = enclosingUnit.resynthesizerContext.resolveTypeRef(
- _entityRef.syntheticReturnType, typeParameterContext,
+ this, _entityRef.syntheticReturnType,
defaultVoid: false, declaredType: true);
}
return _returnType;
@@ -5102,7 +5097,7 @@
GenericFunctionTypeElement get function {
if (_function == null && _unlinkedTypedef != null) {
DartType type = enclosingUnit.resynthesizerContext.resolveTypeRef(
- _unlinkedTypedef.returnType, this,
+ this, _unlinkedTypedef.returnType,
declaredType: true);
if (type is FunctionType) {
Element element = type.element;
@@ -5233,6 +5228,27 @@
return null;
}
+ /**
+ * Return the type of the function defined by this typedef after substituting
+ * the given [typeArguments] for the type parameters defined for this typedef
+ * (but not the type parameters defined by the function). If the number of
+ * [typeArguments] does not match the number of type parameters, then
+ * `dynamic` will be used in place of each of the type arguments.
+ */
+ FunctionType typeAfterSubstitution(List<DartType> typeArguments) {
+ FunctionType functionType = function.type;
+ List<TypeParameterElement> parameterElements = typeParameters;
+ List<DartType> parameterTypes =
+ TypeParameterTypeImpl.getTypes(parameterElements);
+ int parameterCount = parameterTypes.length;
+ if (typeArguments == null ||
+ parameterElements.length != typeArguments.length) {
+ DartType dynamicType = DynamicElementImpl.instance.type;
+ typeArguments = new List<DartType>.filled(parameterCount, dynamicType);
+ }
+ return functionType.substitute2(typeArguments, parameterTypes);
+ }
+
@override
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
@@ -7269,11 +7285,10 @@
@override
DartType get type {
if (_unlinkedVariable != null && _declaredType == null && _type == null) {
- _type = enclosingUnit.resynthesizerContext.resolveLinkedType(
- _unlinkedVariable.inferredTypeSlot, typeParameterContext);
- declaredType = enclosingUnit.resynthesizerContext.resolveTypeRef(
- _unlinkedVariable.type, typeParameterContext,
- declaredType: true);
+ _type = enclosingUnit.resynthesizerContext
+ .resolveLinkedType(this, _unlinkedVariable.inferredTypeSlot);
+ declaredType = enclosingUnit.resynthesizerContext
+ .resolveTypeRef(this, _unlinkedVariable.type, declaredType: true);
}
return super.type;
}
@@ -7775,18 +7790,17 @@
parameterTypeElement.shareParameters(subParameters);
}
parameterTypeElement.returnType = enclosingUnit.resynthesizerContext
- .resolveTypeRef(_unlinkedParam.type, typeParameterContext);
+ .resolveTypeRef(this, _unlinkedParam.type);
FunctionTypeImpl parameterType =
new FunctionTypeImpl.elementWithNameAndArgs(parameterTypeElement,
null, typeParameterContext.allTypeParameterTypes, false);
parameterTypeElement.type = parameterType;
_type = parameterType;
} else {
- _type = enclosingUnit.resynthesizerContext.resolveLinkedType(
- _unlinkedParam.inferredTypeSlot, typeParameterContext);
- declaredType = enclosingUnit.resynthesizerContext.resolveTypeRef(
- _unlinkedParam.type, typeParameterContext,
- declaredType: true);
+ _type = enclosingUnit.resynthesizerContext
+ .resolveLinkedType(this, _unlinkedParam.inferredTypeSlot);
+ declaredType = enclosingUnit.resynthesizerContext
+ .resolveTypeRef(this, _unlinkedParam.type, declaredType: true);
}
}
}
@@ -8283,8 +8297,8 @@
@override
DartType get propagatedType {
if (_unlinkedVariable != null && _propagatedType == null) {
- _propagatedType = enclosingUnit.resynthesizerContext.resolveLinkedType(
- _unlinkedVariable.propagatedTypeSlot, typeParameterContext);
+ _propagatedType = enclosingUnit.resynthesizerContext
+ .resolveLinkedType(this, _unlinkedVariable.propagatedTypeSlot);
}
return _propagatedType;
}
@@ -8359,14 +8373,13 @@
* unresolved, return `null`.
*/
ConstructorElement resolveConstructorRef(
- TypeParameterizedElementMixin typeParameterContext, EntityRef entry);
+ ElementImpl context, EntityRef entry);
/**
* Build the appropriate [DartType] object corresponding to a slot id in the
* [LinkedUnit.types] table.
*/
- DartType resolveLinkedType(
- int slot, TypeParameterizedElementMixin typeParameterContext);
+ DartType resolveLinkedType(ElementImpl context, int slot);
/**
* Resolve an [EntityRef] into a type. If the reference is
@@ -8375,8 +8388,7 @@
* TODO(paulberry): or should we have a class representing an
* unresolved type, for consistency with the full element model?
*/
- DartType resolveTypeRef(
- EntityRef type, TypeParameterizedElementMixin typeParameterContext,
+ DartType resolveTypeRef(ElementImpl context, EntityRef type,
{bool defaultVoid: false,
bool instantiateToBoundsAllowed: true,
bool declaredType: false});
@@ -8578,7 +8590,7 @@
return null;
}
return _bound ??= enclosingUnit.resynthesizerContext.resolveTypeRef(
- _unlinkedTypeParam.bound, enclosingElement,
+ this, _unlinkedTypeParam.bound,
instantiateToBoundsAllowed: false, declaredType: true);
}
return _bound;
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index e38f5fe..4b285cc 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -670,6 +670,45 @@
}
/**
+ * A handle to a [GenericTypeAliasElement].
+ */
+class GenericTypeAliasElementHandle extends ElementHandle
+ implements GenericTypeAliasElement {
+ GenericTypeAliasElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ GenericTypeAliasElement get actualElement =>
+ super.actualElement as GenericTypeAliasElement;
+
+ @override
+ CompilationUnitElement get enclosingElement =>
+ super.enclosingElement as CompilationUnitElement;
+
+ @override
+ GenericFunctionTypeElement get function => actualElement.function;
+
+ @override
+ ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
+
+ @override
+ List<ParameterElement> get parameters => actualElement.parameters;
+
+ @override
+ DartType get returnType => actualElement.returnType;
+
+ @override
+ FunctionType get type => actualElement.type;
+
+ @override
+ List<TypeParameterElement> get typeParameters => actualElement.typeParameters;
+
+ @override
+ FunctionTypeAlias computeNode() => actualElement.computeNode();
+}
+
+/**
* A handle to an [ImportElement].
*/
class ImportElementHandle extends ElementHandle implements ImportElement {
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index e240504..9bbba1a 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/builder.dart';
@@ -225,6 +226,7 @@
elementName: functionName.name + '=');
}
}
+ _setGenericFunctionType(node.returnType, element.returnType);
node.functionExpression.element = element;
_walker._elementHolder?.addFunction(element);
_walk(new ElementWalker.forExecutable(element, _enclosingUnit), () {
@@ -277,10 +279,20 @@
@override
Object visitGenericFunctionType(GenericFunctionType node) {
- GenericFunctionTypeElement element = node.type.element;
- _walk(new ElementWalker.forGenericFunctionType(element), () {
- super.visitGenericFunctionType(node);
- });
+ if (_walker.elementBuilder != null) {
+ _walker.elementBuilder.visitGenericFunctionType(node);
+ } else {
+ DartType type = node.type;
+ if (type != null) {
+ Element element = type.element;
+ if (element is GenericFunctionTypeElement) {
+ _setGenericFunctionType(node.returnType, element.returnType);
+ _walk(new ElementWalker.forGenericFunctionType(element), () {
+ super.visitGenericFunctionType(node);
+ });
+ }
+ }
+ }
return null;
}
@@ -288,8 +300,7 @@
Object visitGenericTypeAlias(GenericTypeAlias node) {
GenericTypeAliasElementImpl element =
_match(node.name, _walker.getTypedef());
- (node.functionType as GenericFunctionTypeImpl)?.type =
- element.function?.type;
+ _setGenericFunctionType(node.functionType, element.function?.type);
_walk(new ElementWalker.forGenericTypeAlias(element), () {
super.visitGenericTypeAlias(node);
});
@@ -357,6 +368,7 @@
elementName: nameOfMethod + '=');
}
}
+ _setGenericFunctionType(node.returnType, element.returnType);
_walk(new ElementWalker.forExecutable(element, _enclosingUnit), () {
super.visitMethodDeclaration(node);
});
@@ -393,10 +405,7 @@
ParameterElement element =
_match(node.identifier, _walker.getParameter());
(node as SimpleFormalParameterImpl).element = element;
- TypeAnnotation type = node.type;
- if (type is GenericFunctionTypeImpl) {
- type.type = element.type;
- }
+ _setGenericFunctionType(node.type, element.type);
_walk(new ElementWalker.forParameter(element), () {
super.visitSimpleFormalParameter(node);
});
@@ -463,10 +472,13 @@
if (_walker.elementBuilder != null) {
return _walker.elementBuilder.visitVariableDeclarationList(node);
} else {
- super.visitVariableDeclarationList(node);
+ node.variables.accept(this);
+ VariableElement firstVariable = node.variables[0].element;
+ _setGenericFunctionType(node.type, firstVariable.type);
+ node.type?.accept(this);
if (node.parent is! FieldDeclaration &&
node.parent is! TopLevelVariableDeclaration) {
- _resolveMetadata(node, node.metadata, node.variables[0].element);
+ _resolveMetadata(node, node.metadata, firstVariable);
}
return null;
}
@@ -538,6 +550,27 @@
}
/**
+ * If the given [typeNode] is a [GenericFunctionType], set its [type].
+ */
+ void _setGenericFunctionType(TypeAnnotation typeNode, DartType type) {
+ if (typeNode is GenericFunctionTypeImpl) {
+ typeNode.type = type;
+ } else if (typeNode is NamedType) {
+ typeNode.type = type;
+ if (type is ParameterizedType) {
+ List<TypeAnnotation> nodes =
+ typeNode.typeArguments?.arguments ?? const [];
+ List<DartType> types = type.typeArguments;
+ if (nodes.length == types.length) {
+ for (int i = 0; i < nodes.length; i++) {
+ _setGenericFunctionType(nodes[i], types[i]);
+ }
+ }
+ }
+ }
+ }
+
+ /**
* Recurses through the element model and AST, verifying that all elements are
* matched.
*
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 6f4768b..e87b77b 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -430,6 +430,10 @@
return true;
}
Token afterReturnType = skipTypeName(_currentToken);
+ if (afterReturnType != null &&
+ _tokenMatchesKeyword(afterReturnType, Keyword.FUNCTION)) {
+ afterReturnType = skipGenericFunctionTypeAfterReturnType(afterReturnType);
+ }
if (afterReturnType == null) {
// There was no return type, but it is optional, so go back to where we
// started.
@@ -544,6 +548,13 @@
// There was no type name, so this can't be a declaration.
return false;
}
+ while (_atGenericFunctionTypeAfterReturnType(token)) {
+ token = skipGenericFunctionTypeAfterReturnType(token);
+ if (token == null) {
+ // There was no type name, so this can't be a declaration.
+ return false;
+ }
+ }
if (token.type != TokenType.IDENTIFIER) {
allowAdditionalTokens = false;
}
@@ -1239,9 +1250,19 @@
CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
Modifiers modifiers = parseModifiers();
Keyword keyword = _currentToken.keyword;
- if (keyword == Keyword.VOID) {
- TypeName returnType = astFactory.typeName(
- astFactory.simpleIdentifier(getAndAdvance()), null);
+ if (keyword == Keyword.VOID ||
+ _atGenericFunctionTypeAfterReturnType(_currentToken)) {
+ TypeAnnotation returnType;
+ if (keyword == Keyword.VOID) {
+ if (_atGenericFunctionTypeAfterReturnType(_peek())) {
+ returnType = parseTypeAnnotation(false);
+ } else {
+ returnType = astFactory.typeName(
+ astFactory.simpleIdentifier(getAndAdvance()), null);
+ }
+ } else {
+ returnType = parseTypeAnnotation(false);
+ }
keyword = _currentToken.keyword;
Token next = _peek();
bool isFollowedByIdentifier = _tokenMatchesIdentifier(next);
@@ -1267,28 +1288,25 @@
_validateModifiersForGetterOrSetterOrMethod(modifiers);
return _parseMethodDeclarationAfterReturnType(commentAndMetadata,
modifiers.externalKeyword, modifiers.staticKeyword, returnType);
- } else {
- //
- // We have found an error of some kind. Try to recover.
- //
- if (_matchesIdentifier()) {
- if (_peek().matchesAny(const <TokenType>[
+ } else if (_matchesIdentifier() &&
+ _peek().matchesAny(const <TokenType>[
TokenType.EQ,
TokenType.COMMA,
TokenType.SEMICOLON
])) {
- //
- // We appear to have a variable declaration with a type of "void".
- //
- _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType);
- return parseInitializedIdentifierList(
- commentAndMetadata,
- modifiers.staticKeyword,
- modifiers.covariantKeyword,
- _validateModifiersForField(modifiers),
- returnType);
- }
+ if (returnType is! GenericFunctionType) {
+ _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType);
}
+ return parseInitializedIdentifierList(
+ commentAndMetadata,
+ modifiers.staticKeyword,
+ modifiers.covariantKeyword,
+ _validateModifiersForField(modifiers),
+ returnType);
+ } else {
+ //
+ // We have found an error of some kind. Try to recover.
+ //
if (_isOperator(_currentToken)) {
//
// We appear to have found an operator declaration without the
@@ -2036,9 +2054,19 @@
} else if (keyword == Keyword.ENUM) {
_validateModifiersForEnum(modifiers);
return parseEnumDeclaration(commentAndMetadata);
- } else if (keyword == Keyword.VOID) {
- TypeName returnType = astFactory.typeName(
- astFactory.simpleIdentifier(getAndAdvance()), null);
+ } else if (keyword == Keyword.VOID ||
+ _atGenericFunctionTypeAfterReturnType(_currentToken)) {
+ TypeAnnotation returnType;
+ if (keyword == Keyword.VOID) {
+ if (_atGenericFunctionTypeAfterReturnType(next)) {
+ returnType = parseTypeAnnotation(false);
+ } else {
+ returnType = astFactory.typeName(
+ astFactory.simpleIdentifier(getAndAdvance()), null);
+ }
+ } else {
+ returnType = parseTypeAnnotation(false);
+ }
keyword = _currentToken.keyword;
next = _peek();
if ((keyword == Keyword.GET || keyword == Keyword.SET) &&
@@ -2063,28 +2091,25 @@
_validateModifiersForTopLevelFunction(modifiers);
return parseFunctionDeclaration(
commentAndMetadata, modifiers.externalKeyword, returnType);
- } else {
- //
- // We have found an error of some kind. Try to recover.
- //
- if (_matchesIdentifier()) {
- if (next.matchesAny(const <TokenType>[
+ } else if (_matchesIdentifier() &&
+ next.matchesAny(const <TokenType>[
TokenType.EQ,
TokenType.COMMA,
TokenType.SEMICOLON
])) {
- //
- // We appear to have a variable declaration with a type of "void".
- //
- _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType);
- return astFactory.topLevelVariableDeclaration(
- commentAndMetadata.comment,
- commentAndMetadata.metadata,
- parseVariableDeclarationListAfterType(null,
- _validateModifiersForTopLevelVariable(modifiers), null),
- _expect(TokenType.SEMICOLON));
- }
+ if (returnType is! GenericFunctionType) {
+ _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType);
}
+ return astFactory.topLevelVariableDeclaration(
+ commentAndMetadata.comment,
+ commentAndMetadata.metadata,
+ parseVariableDeclarationListAfterType(null,
+ _validateModifiersForTopLevelVariable(modifiers), returnType),
+ _expect(TokenType.SEMICOLON));
+ } else {
+ //
+ // We have found an error of some kind. Try to recover.
+ //
_reportErrorForToken(
ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken);
return null;
@@ -4024,8 +4049,13 @@
return parseVariableDeclarationStatementAfterMetadata(
commentAndMetadata);
} else if (keyword == Keyword.VOID) {
- TypeName returnType = astFactory.typeName(
- astFactory.simpleIdentifier(getAndAdvance()), null);
+ TypeAnnotation returnType;
+ if (_atGenericFunctionTypeAfterReturnType(_peek())) {
+ returnType = parseTypeAnnotation(false);
+ } else {
+ returnType = astFactory.typeName(
+ astFactory.simpleIdentifier(getAndAdvance()), null);
+ }
Token next = _currentToken.next;
if (_matchesIdentifier() &&
next.matchesAny(const <TokenType>[
@@ -4036,24 +4066,22 @@
])) {
return _parseFunctionDeclarationStatementAfterReturnType(
commentAndMetadata, returnType);
- } else {
- //
- // We have found an error of some kind. Try to recover.
- //
- if (_matchesIdentifier()) {
- if (next.matchesAny(const <TokenType>[
+ } else if (_matchesIdentifier() &&
+ next.matchesAny(const <TokenType>[
TokenType.EQ,
TokenType.COMMA,
TokenType.SEMICOLON
])) {
- //
- // We appear to have a variable declaration with a type of "void".
- //
- _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType);
- return parseVariableDeclarationStatementAfterMetadata(
- commentAndMetadata);
- }
- } else if (_matches(TokenType.CLOSE_CURLY_BRACKET)) {
+ if (returnType is! GenericFunctionType) {
+ _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType);
+ }
+ return _parseVariableDeclarationStatementAfterType(
+ commentAndMetadata, null, returnType);
+ } else {
+ //
+ // We have found an error of some kind. Try to recover.
+ //
+ if (_matches(TokenType.CLOSE_CURLY_BRACKET)) {
//
// We appear to have found an incomplete statement at the end of a
// block. Parse it as a variable declaration.
@@ -4106,7 +4134,47 @@
return astFactory
.emptyStatement(_createSyntheticToken(TokenType.SEMICOLON));
}
- } else if (_inGenerator && _matchesString(_YIELD)) {
+ } else if (_atGenericFunctionTypeAfterReturnType(_currentToken)) {
+ TypeAnnotation returnType = parseTypeAnnotation(false);
+ Token next = _currentToken.next;
+ if (_matchesIdentifier() &&
+ next.matchesAny(const <TokenType>[
+ TokenType.OPEN_PAREN,
+ TokenType.OPEN_CURLY_BRACKET,
+ TokenType.FUNCTION,
+ TokenType.LT
+ ])) {
+ return _parseFunctionDeclarationStatementAfterReturnType(
+ commentAndMetadata, returnType);
+ } else if (_matchesIdentifier() &&
+ next.matchesAny(const <TokenType>[
+ TokenType.EQ,
+ TokenType.COMMA,
+ TokenType.SEMICOLON
+ ])) {
+ if (returnType is! GenericFunctionType) {
+ _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType);
+ }
+ return _parseVariableDeclarationStatementAfterType(
+ commentAndMetadata, null, returnType);
+ } else {
+ //
+ // We have found an error of some kind. Try to recover.
+ //
+ if (_matches(TokenType.CLOSE_CURLY_BRACKET)) {
+ //
+ // We appear to have found an incomplete statement at the end of a
+ // block. Parse it as a variable declaration.
+ //
+ return _parseVariableDeclarationStatementAfterType(
+ commentAndMetadata, null, returnType);
+ }
+ _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT);
+ // TODO(brianwilkerson) Recover from this error.
+ return astFactory
+ .emptyStatement(_createSyntheticToken(TokenType.SEMICOLON));
+ }
+ } else if (_inGenerator && _matchesKeyword(Keyword.YIELD)) {
return parseYieldStatement();
} else if (_inAsync && _matchesString(_AWAIT)) {
if (_tokenMatchesKeyword(_peek(), Keyword.FOR)) {
@@ -4623,8 +4691,12 @@
*/
TypeAnnotation parseReturnType(bool inExpression) {
if (_currentToken.keyword == Keyword.VOID) {
- return astFactory.typeName(
- astFactory.simpleIdentifier(getAndAdvance()), null);
+ if (_atGenericFunctionTypeAfterReturnType(_peek())) {
+ return parseTypeAnnotation(false);
+ } else {
+ return astFactory.typeName(
+ astFactory.simpleIdentifier(getAndAdvance()), null);
+ }
} else {
return parseTypeAnnotation(inExpression);
}
@@ -5418,7 +5490,7 @@
if (!_tokenMatches(startToken, TokenType.OPEN_PAREN)) {
return null;
}
- return (startToken as BeginToken).endToken;
+ return (startToken as BeginToken).endToken.next;
}
/**
@@ -5485,6 +5557,9 @@
*/
Token skipReturnType(Token startToken) {
if (_tokenMatchesKeyword(startToken, Keyword.VOID)) {
+ if (_atGenericFunctionTypeAfterReturnType(_peek())) {
+ return skipTypeAnnotation(startToken);
+ }
return startToken.next;
} else {
return skipTypeAnnotation(startToken);
@@ -5652,7 +5727,7 @@
} else if (_tokenMatches(next, TokenType.GT)) {
depth--;
if (depth == 0) {
- return next;
+ return next.next;
}
}
previous = next;
@@ -7160,6 +7235,9 @@
}
Keyword keyword = _currentToken.keyword;
if (keyword == Keyword.VOID) {
+ if (_atGenericFunctionTypeAfterReturnType(_peek())) {
+ return parseTypeAnnotation(false);
+ }
return astFactory.typeName(
astFactory.simpleIdentifier(getAndAdvance()), null);
} else if (_matchesIdentifier()) {
@@ -7532,7 +7610,9 @@
* variableDeclarationList ';'
*/
VariableDeclarationStatement _parseVariableDeclarationStatementAfterType(
- CommentAndMetadata commentAndMetadata, Token keyword, TypeName type) {
+ CommentAndMetadata commentAndMetadata,
+ Token keyword,
+ TypeAnnotation type) {
VariableDeclarationList variableList =
parseVariableDeclarationListAfterType(
commentAndMetadata, keyword, type);
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index ccfa988..502fddf6 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -8466,31 +8466,18 @@
return undefinedType;
} else if (type is FunctionType) {
Element element = type.element;
- if (annotation is TypeName && element is GenericTypeAliasElement) {
- List<TypeParameterElement> parameterElements = element.typeParameters;
- FunctionType functionType = element.function.type;
- if (parameterElements.isNotEmpty) {
- List<DartType> parameterTypes =
- TypeParameterTypeImpl.getTypes(parameterElements);
- int parameterCount = parameterTypes.length;
- TypeArgumentList argumentList = annotation.typeArguments;
- List<DartType> typeArguments;
- if (argumentList != null) {
- List<TypeAnnotation> arguments = argumentList.arguments;
- int argumentCount = arguments.length;
- if (argumentCount == parameterCount) {
- typeArguments = new List<DartType>(parameterCount);
- for (int i = 0; i < parameterCount; i++) {
- typeArguments[i] = _getType(arguments[i]);
- }
- }
+ if (annotation is TypeName && element is GenericTypeAliasElementImpl) {
+ TypeArgumentList argumentList = annotation.typeArguments;
+ List<DartType> typeArguments = null;
+ if (argumentList != null) {
+ List<TypeAnnotation> arguments = argumentList.arguments;
+ int argumentCount = arguments.length;
+ typeArguments = new List<DartType>(argumentCount);
+ for (int i = 0; i < argumentCount; i++) {
+ typeArguments[i] = _getType(arguments[i]);
}
- typeArguments ??=
- new List<DartType>.filled(parameterCount, dynamicType);
- functionType =
- functionType.substitute2(typeArguments, parameterTypes);
}
- return functionType;
+ return element.typeAfterSubstitution(typeArguments);
}
}
return type;
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 3119c64..d7604a3 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -1132,7 +1132,12 @@
/**
* The entity being referred to does not exist.
*/
- unresolved
+ unresolved,
+
+ /**
+ * The entity is a typedef expressed using generic function type syntax.
+ */
+ genericFunctionTypedef
}
/**
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 5c70e57..673e9d8 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -683,7 +683,7 @@
*/
InterfaceType _computeInterfaceType(EntityRef typeRef) {
if (typeRef != null) {
- DartType type = enclosingElement.resolveTypeRef(typeRef, this);
+ DartType type = enclosingElement.resolveTypeRef(this, typeRef);
if (type is InterfaceType && !type.element.isEnum) {
return type;
}
@@ -1000,11 +1000,10 @@
/**
* Compute the type referred to by the given linked type [slot] (interpreted
- * relative to [typeParameterContext]). If there is no inferred type in the
+ * in [context]). If there is no inferred type in the
* given slot, `dynamic` is returned.
*/
- DartType getLinkedType(
- int slot, TypeParameterizedElementMixin typeParameterContext);
+ DartType getLinkedType(ElementImpl context, int slot);
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
@@ -1076,8 +1075,7 @@
}
@override
- DartType resolveTypeRef(
- EntityRef type, TypeParameterizedElementMixin typeParameterContext,
+ DartType resolveTypeRef(ElementImpl context, EntityRef type,
{bool defaultVoid: false,
bool instantiateToBoundsAllowed: true,
bool declaredType: false}) {
@@ -1089,7 +1087,8 @@
}
}
if (type.paramReference != 0) {
- return typeParameterContext.getTypeParameterType(type.paramReference);
+ return context.typeParameterContext
+ .getTypeParameterType(type.paramReference);
} else if (type.syntheticReturnType != null) {
// TODO(paulberry): implement.
throw new UnimplementedError();
@@ -1099,7 +1098,7 @@
} else {
DartType getTypeArgument(int i) {
if (i < type.typeArguments.length) {
- return resolveTypeRef(type.typeArguments[i], typeParameterContext);
+ return resolveTypeRef(context, type.typeArguments[i]);
} else if (!instantiateToBoundsAllowed) {
// Do not allow buildType to instantiate the bounds; force dynamic.
return DynamicTypeImpl.instance;
@@ -1279,8 +1278,7 @@
}
@override
- DartType getLinkedType(
- int slot, TypeParameterizedElementMixin typeParameterContext) {
+ DartType getLinkedType(ElementImpl context, int slot) {
// This method should only be called on compilation units that come from
// dependencies, never on compilation units that are part of the current
// build unit.
@@ -1406,10 +1404,9 @@
bool get isInBuildUnit => false;
@override
- DartType getLinkedType(
- int slot, TypeParameterizedElementMixin typeParameterContext) {
+ DartType getLinkedType(ElementImpl context, int slot) {
if (slot < _linkedTypeRefs.length) {
- return resolveTypeRef(_linkedTypeRefs[slot], typeParameterContext);
+ return resolveTypeRef(context, _linkedTypeRefs[slot]);
} else {
return DynamicTypeImpl.instance;
}
@@ -1832,7 +1829,7 @@
return null;
} else {
return _declaredReturnType ??=
- compilationUnit.resolveTypeRef(_unlinkedExecutable.returnType, this);
+ compilationUnit.resolveTypeRef(this, _unlinkedExecutable.returnType);
}
}
@@ -1879,7 +1876,7 @@
_inferredReturnType = _computeDefaultReturnType();
} else {
_inferredReturnType = compilationUnit.getLinkedType(
- _unlinkedExecutable.inferredReturnTypeSlot, this);
+ this, _unlinkedExecutable.inferredReturnTypeSlot);
}
}
return _inferredReturnType;
@@ -2327,8 +2324,7 @@
if (ref.typeArguments.isNotEmpty) {
return constructorElement.enclosingClass.buildType((int i) {
if (i < ref.typeArguments.length) {
- return unit.resolveTypeRef(
- ref.typeArguments[i], function.typeParameterContext);
+ return unit.resolveTypeRef(function, ref.typeArguments[i]);
} else {
return null;
}
@@ -2528,7 +2524,7 @@
DartType _getNextTypeRef() {
EntityRef ref = _getNextRef();
- return unit.resolveTypeRef(ref, function.typeParameterContext);
+ return unit.resolveTypeRef(function, ref);
}
List<DartType> _getTypeArguments() {
@@ -2885,7 +2881,7 @@
_returnType = DynamicTypeImpl.instance;
} else {
_returnType = enclosingElement.compilationUnit.resolveTypeRef(
- enclosingElement._unlinkedParam.type, typeParameterContext);
+ enclosingElement, enclosingElement._unlinkedParam.type);
}
}
return _returnType;
@@ -3200,7 +3196,7 @@
@override
DartType get returnType => _returnType ??=
- enclosingElement.resolveTypeRef(_unlinkedTypedef.returnType, this);
+ enclosingElement.resolveTypeRef(this, _unlinkedTypedef.returnType);
@override
TypeParameterizedElementMixin get typeParameterContext => this;
@@ -4191,14 +4187,14 @@
} else if (_unlinkedParam.type == null) {
if (!compilationUnit.isInBuildUnit) {
_inferredType = compilationUnit.getLinkedType(
- _unlinkedParam.inferredTypeSlot, _typeParameterContext);
+ this, _unlinkedParam.inferredTypeSlot);
return _inferredType;
} else {
_declaredType = DynamicTypeImpl.instance;
}
} else {
- _declaredType = compilationUnit.resolveTypeRef(
- _unlinkedParam.type, _typeParameterContext);
+ _declaredType =
+ compilationUnit.resolveTypeRef(this, _unlinkedParam.type);
}
}
return _declaredType;
@@ -4210,6 +4206,11 @@
_inferredType = inferredType;
}
+ @override
+ TypeParameterizedElementMixin get typeParameterContext {
+ return _typeParameterContext;
+ }
+
/**
* Store the results of type inference for this parameter in
* [compilationUnit].
@@ -5181,8 +5182,8 @@
if (unlinkedVariable.type == null) {
return null;
} else {
- return _declaredType ??= compilationUnit.resolveTypeRef(
- unlinkedVariable.type, _typeParameterContext);
+ return _declaredType ??=
+ compilationUnit.resolveTypeRef(this, unlinkedVariable.type);
}
}
@@ -5221,7 +5222,7 @@
_inferredType = DynamicTypeImpl.instance;
} else {
_inferredType = compilationUnit.getLinkedType(
- unlinkedVariable.inferredTypeSlot, _typeParameterContext);
+ this, unlinkedVariable.inferredTypeSlot);
}
}
return _inferredType;
@@ -5280,6 +5281,11 @@
// TODO(paulberry): store inferred type.
}
+ @override
+ TypeParameterizedElementMixin get typeParameterContext {
+ return _typeParameterContext;
+ }
+
/**
* The context in which type parameters should be interpreted, or `null` if
* there are no type parameters in scope.
diff --git a/pkg/analyzer/lib/src/summary/prelink.dart b/pkg/analyzer/lib/src/summary/prelink.dart
index 1e64b4a..e3c4401 100644
--- a/pkg/analyzer/lib/src/summary/prelink.dart
+++ b/pkg/analyzer/lib/src/summary/prelink.dart
@@ -383,10 +383,18 @@
executable.typeParameters.length));
}
for (UnlinkedTypedef typedef in unit.typedefs) {
- privateNamespace.add(
- typedef.name,
- new _Meaning(unitNum, ReferenceKind.typedef, 0,
- typedef.typeParameters.length));
+ ReferenceKind kind;
+ switch (typedef.style) {
+ case TypedefStyle.functionType:
+ kind = ReferenceKind.typedef;
+ break;
+ case TypedefStyle.genericFunctionType:
+ kind = ReferenceKind.genericFunctionTypedef;
+ break;
+ }
+ assert(kind != null);
+ privateNamespace.add(typedef.name,
+ new _Meaning(unitNum, kind, 0, typedef.typeParameters.length));
}
for (UnlinkedVariable variable in unit.variables) {
privateNamespace.add(variable.name,
diff --git a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
index 203043a..b11701b 100644
--- a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
+++ b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
@@ -177,6 +177,12 @@
}
@override
+ visitGenericTypeAlias(GenericTypeAlias node) {
+ addNameIfPublic(node.name.name, ReferenceKind.genericFunctionTypedef,
+ node.typeParameters?.typeParameters?.length ?? 0);
+ }
+
+ @override
visitPartDirective(PartDirective node) {
parts.add(node.uri.stringValue ?? '');
}
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index da24aba..8550ecd 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -584,8 +584,7 @@
*/
TypeAnnotation _newTypeName() {
EntityRef typeRef = uc.references[refPtr++];
- DartType type =
- resynthesizer.buildType(typeRef, context?.typeParameterContext);
+ DartType type = resynthesizer.buildType(context, typeRef);
return _buildTypeAst(type);
}
@@ -633,7 +632,7 @@
return;
}
InterfaceType definingType = resynthesizer._createConstructorDefiningType(
- context?.typeParameterContext, info, ref.typeArguments);
+ context, info, ref.typeArguments);
constructorElement =
resynthesizer._getConstructorForInfo(definingType, info);
typeNode = _buildTypeAst(definingType);
@@ -938,6 +937,9 @@
case ReferenceKind.typedef:
return new FunctionTypeAliasElementHandle(
summaryResynthesizer, location);
+ case ReferenceKind.genericFunctionTypedef:
+ return new GenericTypeAliasElementHandle(
+ summaryResynthesizer, location);
case ReferenceKind.topLevelFunction:
return new FunctionElementHandle(summaryResynthesizer, location);
case ReferenceKind.topLevelPropertyAccessor:
@@ -1314,6 +1316,11 @@
}
// Done.
return type;
+ } else if (element is GenericTypeAliasElementHandle) {
+ GenericTypeAliasElementImpl actualElement = element.actualElement;
+ List<DartType> argumentTypes =
+ new List.generate(numTypeArguments, getTypeArgument);
+ return actualElement.typeAfterSubstitution(argumentTypes);
} else if (element is FunctionTypedElement) {
if (element is FunctionTypeAliasElementHandle) {
List<DartType> typeArguments;
@@ -1421,24 +1428,21 @@
@override
ConstructorElement resolveConstructorRef(
- TypeParameterizedElementMixin typeParameterContext, EntityRef entry) {
- return _unitResynthesizer._getConstructorForEntry(
- typeParameterContext, entry);
+ ElementImpl context, EntityRef entry) {
+ return _unitResynthesizer._getConstructorForEntry(context, entry);
}
@override
- DartType resolveLinkedType(
- int slot, TypeParameterizedElementMixin typeParameterContext) {
- return _unitResynthesizer.buildLinkedType(slot, typeParameterContext);
+ DartType resolveLinkedType(ElementImpl context, int slot) {
+ return _unitResynthesizer.buildLinkedType(context, slot);
}
@override
- DartType resolveTypeRef(
- EntityRef type, TypeParameterizedElementMixin typeParameterContext,
+ DartType resolveTypeRef(ElementImpl context, EntityRef type,
{bool defaultVoid: false,
bool instantiateToBoundsAllowed: true,
bool declaredType: false}) {
- return _unitResynthesizer.buildType(type, typeParameterContext,
+ return _unitResynthesizer.buildType(context, type,
defaultVoid: defaultVoid,
instantiateToBoundsAllowed: instantiateToBoundsAllowed,
declaredType: declaredType);
@@ -1607,8 +1611,7 @@
* Build the appropriate [DartType] object corresponding to a slot id in the
* [LinkedUnit.types] table.
*/
- DartType buildLinkedType(
- int slot, TypeParameterizedElementMixin typeParameterContext) {
+ DartType buildLinkedType(ElementImpl context, int slot) {
if (slot == 0) {
// A slot id of 0 means there is no [DartType] object to build.
return null;
@@ -1619,7 +1622,7 @@
// stored in this slot.
return null;
}
- return buildType(type, typeParameterContext);
+ return buildType(context, type);
}
/**
@@ -1628,8 +1631,7 @@
* deserialized, so handles are used to avoid having to deserialize other
* libraries in the process.
*/
- DartType buildType(
- EntityRef type, TypeParameterizedElementMixin typeParameterContext,
+ DartType buildType(ElementImpl context, EntityRef type,
{bool defaultVoid: false,
bool instantiateToBoundsAllowed: true,
bool declaredType: false}) {
@@ -1641,20 +1643,20 @@
}
}
if (type.paramReference != 0) {
- return typeParameterContext.getTypeParameterType(type.paramReference);
+ return context.typeParameterContext
+ .getTypeParameterType(type.paramReference);
} else if (type.entityKind == EntityRefKind.genericFunctionType) {
GenericFunctionTypeElement element =
- new GenericFunctionTypeElementImpl.forSerialized(
- type, typeParameterContext);
+ new GenericFunctionTypeElementImpl.forSerialized(context, type);
return element.type;
} else if (type.syntheticReturnType != null) {
- FunctionElementImpl element =
- new FunctionElementImpl_forLUB(unit, typeParameterContext, type);
+ FunctionElementImpl element = new FunctionElementImpl_forLUB(
+ unit, context.typeParameterContext, type);
return element.type;
} else {
DartType getTypeArgument(int i) {
if (i < type.typeArguments.length) {
- return buildType(type.typeArguments[i], typeParameterContext,
+ return buildType(context, type.typeArguments[i],
declaredType: declaredType);
} else {
return DynamicTypeImpl.instance;
@@ -1839,6 +1841,11 @@
summaryResynthesizer, location);
isDeclarableType = true;
break;
+ case ReferenceKind.genericFunctionTypedef:
+ element = new GenericTypeAliasElementHandle(
+ summaryResynthesizer, location);
+ isDeclarableType = true;
+ break;
case ReferenceKind.variable:
Element enclosingElement = enclosingInfo.element;
if (enclosingElement is ExecutableElement) {
@@ -1898,18 +1905,15 @@
* [typeArgumentRefs] to the given linked [info]. Return [DynamicTypeImpl]
* if the [info] is unresolved.
*/
- DartType _createConstructorDefiningType(
- TypeParameterizedElementMixin typeParameterContext,
- _ReferenceInfo info,
- List<EntityRef> typeArgumentRefs) {
+ DartType _createConstructorDefiningType(ElementImpl context,
+ _ReferenceInfo info, List<EntityRef> typeArgumentRefs) {
bool isClass = info.element is ClassElement;
_ReferenceInfo classInfo = isClass ? info : info.enclosing;
if (classInfo == null) {
return DynamicTypeImpl.instance;
}
- List<DartType> typeArguments = typeArgumentRefs
- .map((t) => buildType(t, typeParameterContext))
- .toList();
+ List<DartType> typeArguments =
+ typeArgumentRefs.map((t) => buildType(context, t)).toList();
return classInfo.buildType(true, typeArguments.length, (i) {
if (i < typeArguments.length) {
return typeArguments[i];
@@ -1923,10 +1927,10 @@
* Return the [ConstructorElement] corresponding to the given [entry].
*/
ConstructorElement _getConstructorForEntry(
- TypeParameterizedElementMixin typeParameterContext, EntityRef entry) {
+ ElementImpl context, EntityRef entry) {
_ReferenceInfo info = getReferenceInfo(entry.reference);
- DartType type = _createConstructorDefiningType(
- typeParameterContext, info, entry.typeArguments);
+ DartType type =
+ _createConstructorDefiningType(context, info, entry.typeArguments);
if (type is InterfaceType) {
return _getConstructorForInfo(type, info);
}
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index 36fda8b..1c2ed1d 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -799,11 +799,11 @@
scopes.add(typeParameterScope);
EntityRefBuilder b = new EntityRefBuilder();
b.entityKind = EntityRefKind.genericFunctionType;
+ b.typeParameters =
+ serializeTypeParameters(node.typeParameters, typeParameterScope);
b.syntheticReturnType = node.returnType == null
? serializeDynamic()
: serializeTypeName(node.returnType);
- b.typeParameters =
- serializeTypeParameters(node.typeParameters, typeParameterScope);
b.syntheticParams = node.parameters.parameters
.map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
.toList();
diff --git a/pkg/analyzer/test/dart/element/builder_test.dart b/pkg/analyzer/test/dart/element/builder_test.dart
index ecbb202..033e66e 100644
--- a/pkg/analyzer/test/dart/element/builder_test.dart
+++ b/pkg/analyzer/test/dart/element/builder_test.dart
@@ -1113,6 +1113,19 @@
expect(variableElement.initializer, isNotNull);
}
+ void test_genericFunction_isExpression() {
+ buildElementsForText('main(p) { p is Function(int a, String); }');
+ var main = compilationUnit.declarations[0] as FunctionDeclaration;
+ var body = main.functionExpression.body as BlockFunctionBody;
+ var statement = body.block.statements[0] as ExpressionStatement;
+ var expression = statement.expression as IsExpression;
+ var typeNode = expression.type as GenericFunctionType;
+ var typeElement = typeNode.type.element as GenericFunctionTypeElementImpl;
+ expect(typeElement.parameters, hasLength(2));
+ expect(typeElement.parameters[0].name, 'a');
+ expect(typeElement.parameters[1].name, '');
+ }
+
void test_visitDefaultFormalParameter_local() {
CompilationUnit unit = parseCompilationUnit('''
main() {
@@ -1183,6 +1196,16 @@
*/
void checkMetadata(Element element);
+ void test_genericFunction_asTopLevelVariableType() {
+ buildElementsForText('int Function(int a, String) v;');
+ var v = compilationUnit.declarations[0] as TopLevelVariableDeclaration;
+ var typeNode = v.variables.type as GenericFunctionType;
+ var typeElement = typeNode.type.element as GenericFunctionTypeElementImpl;
+ expect(typeElement.parameters, hasLength(2));
+ expect(typeElement.parameters[0].name, 'a');
+ expect(typeElement.parameters[1].name, '');
+ }
+
void test_metadata_fieldDeclaration() {
List<FieldElement> fields =
buildElementsForText('class C { @a int x, y; }').types[0].fields;
diff --git a/pkg/analyzer/test/generated/declaration_resolver_test.dart b/pkg/analyzer/test/generated/declaration_resolver_test.dart
index 2a034bc..8b0a4e3 100644
--- a/pkg/analyzer/test/generated/declaration_resolver_test.dart
+++ b/pkg/analyzer/test/generated/declaration_resolver_test.dart
@@ -468,6 +468,109 @@
expect(getterName.staticElement, same(setterElement));
}
+ test_genericFunction_asFunctionReturnType() async {
+ String code = r'''
+Function(int, String) f() => null;
+''';
+ CompilationUnit unit = await resolveSource(code);
+ // re-resolve
+ _cloneResolveUnit(unit);
+ // no other validations than built into DeclarationResolver
+ }
+
+ test_genericFunction_asGenericFunctionReturnType() async {
+ String code = r'''
+typedef F<T> = int Function(T t, S s) Function<S>(int);
+''';
+ CompilationUnit unit = await resolveSource(code);
+ // re-resolve
+ _cloneResolveUnit(unit);
+ // no other validations than built into DeclarationResolver
+ }
+
+ test_genericFunction_asMethodReturnType() async {
+ String code = r'''
+class C {
+ Function(int, String) m() => null;
+}
+''';
+ CompilationUnit unit = await resolveSource(code);
+ // re-resolve
+ _cloneResolveUnit(unit);
+ // no other validations than built into DeclarationResolver
+ }
+
+ test_genericFunction_asParameterReturnType() async {
+ String code = r'''
+f(Function(int, String) p) => null;
+''';
+ CompilationUnit unit = await resolveSource(code);
+ // re-resolve
+ _cloneResolveUnit(unit);
+ // no other validations than built into DeclarationResolver
+ }
+
+ test_genericFunction_asTopLevelVariableType() async {
+ String code = r'''
+int Function(int, String) v;
+''';
+ CompilationUnit unit = await resolveSource(code);
+ // re-resolve
+ _cloneResolveUnit(unit);
+ // no other validations than built into DeclarationResolver
+ }
+
+ test_genericFunction_asTypeArgument() async {
+ String code = r'''
+List<Function(int)> v;
+''';
+ CompilationUnit unit = await resolveSource(code);
+ // re-resolve
+ _cloneResolveUnit(unit);
+ // no other validations than built into DeclarationResolver
+ }
+
+ test_genericFunction_asTypeArgument_lessNodes() async {
+ String code = r'''
+Map<Function<int>> v;
+''';
+ CompilationUnit unit = await resolveSource(code);
+ // re-resolve
+ _cloneResolveUnit(unit);
+ // no other validations than built into DeclarationResolver
+ }
+
+ test_genericFunction_asTypeArgument_moreNodes() async {
+ String code = r'''
+List<Function<int>, Function<String>> v;
+''';
+ CompilationUnit unit = await resolveSource(code);
+ // re-resolve
+ _cloneResolveUnit(unit);
+ // no other validations than built into DeclarationResolver
+ }
+
+ test_genericFunction_asTypeArgument_noNodes() async {
+ String code = r'''
+List v;
+''';
+ CompilationUnit unit = await resolveSource(code);
+ // re-resolve
+ _cloneResolveUnit(unit);
+ // no other validations than built into DeclarationResolver
+ }
+
+ test_genericFunction_asTypeArgument_ofInitializer() async {
+ String code = r'''
+var v = <Function(int)>[];
+''';
+ CompilationUnit unit = await resolveSource(code);
+ CompilationUnit newUnit = _cloneResolveUnit(unit);
+ var v = newUnit.declarations[0] as TopLevelVariableDeclaration;
+ var initializer = v.variables.variables[0].initializer as ListLiteral;
+ expect(initializer.typeArguments.arguments[0].type, isNotNull);
+ }
+
test_invalid_functionDeclaration_getter_inFunction() async {
String code = r'''
var v = (() {
diff --git a/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart
index be0f9b5..b18fe32 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart
@@ -16,9 +16,4 @@
class NonErrorResolverTest_Driver extends NonErrorResolverTest {
@override
bool get enableNewAnalysisDriver => true;
-
- @failingTest
- test_genericTypeAlias_fieldAndReturnType() async {
- return super.test_genericTypeAlias_fieldAndReturnType();
- }
}
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index e89057b..e516d5d 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -2158,7 +2158,7 @@
verify([source]);
}
- test_genericTypeAlias_fieldAndReturnType() async {
+ test_genericTypeAlias_fieldAndReturnType_noTypeParameters() async {
Source source = addSource(r'''
typedef Foo = int Function<T>(T x);
int foo<T>(T x) => 3;
@@ -2179,6 +2179,48 @@
verify([source]);
}
+ test_genericTypeAlias_fieldAndReturnType_typeParameters_arguments() async {
+ Source source = addSource(r'''
+typedef Foo<S> = S Function<T>(T x);
+int foo<T>(T x) => 3;
+Foo<int> bar() => foo;
+void test1() {
+ bar()<String>("hello");
+}
+
+class A {
+ Foo<int> f;
+ void test() {
+ f<String>("hello");
+ }
+}
+''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ test_genericTypeAlias_fieldAndReturnType_typeParameters_noArguments() async {
+ Source source = addSource(r'''
+typedef Foo<S> = S Function<T>(T x);
+int foo<T>(T x) => 3;
+Foo bar() => foo;
+void test1() {
+ bar()<String>("hello");
+}
+
+class A {
+ Foo f;
+ void test() {
+ f<String>("hello");
+ }
+}
+''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_genericTypeAlias_noTypeParameters() async {
Source source = addSource(r'''
typedef Foo = int Function<T>(T x);
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 20c2daa..e577850 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -4106,18 +4106,12 @@
void test_voidVariable_statement_initializer() {
parseStatement("void x = 0;");
- assertErrorsWithCodes([
- ParserErrorCode.VOID_VARIABLE,
- ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE
- ]);
+ assertErrorsWithCodes([ParserErrorCode.VOID_VARIABLE]);
}
void test_voidVariable_statement_noInitializer() {
parseStatement("void x;");
- assertErrorsWithCodes([
- ParserErrorCode.VOID_VARIABLE,
- ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE
- ]);
+ assertErrorsWithCodes([ParserErrorCode.VOID_VARIABLE]);
}
void test_withBeforeExtends() {
@@ -10027,6 +10021,50 @@
expect(arguments, hasLength(3));
}
+ void test_parseClassMember_field_gftType_gftReturnType() {
+ createParser('''
+Function(int) Function(String) v;
+''');
+ ClassMember member = parser.parseClassMember('C');
+ listener.assertNoErrors();
+ expect(member, new isInstanceOf<FieldDeclaration>());
+ VariableDeclarationList fields = (member as FieldDeclaration).fields;
+ expect(fields.type, new isInstanceOf<GenericFunctionType>());
+ }
+
+ void test_parseClassMember_field_gftType_noReturnType() {
+ createParser('''
+Function(int, String) v;
+''');
+ ClassMember member = parser.parseClassMember('C');
+ listener.assertNoErrors();
+ expect(member, new isInstanceOf<FieldDeclaration>());
+ VariableDeclarationList fields = (member as FieldDeclaration).fields;
+ expect(fields.type, new isInstanceOf<GenericFunctionType>());
+ }
+
+ void test_parseClassMember_method_gftReturnType() {
+ createParser('''
+void Function<A>(core.List<core.int> x) m() => null;
+''');
+ ClassMember member = parser.parseClassMember('C');
+ listener.assertNoErrors();
+ expect(member, new isInstanceOf<MethodDeclaration>());
+ expect((member as MethodDeclaration).body,
+ new isInstanceOf<ExpressionFunctionBody>());
+ }
+
+ void test_parseClassMember_method_noReturnType() {
+ createParser('''
+Function<A>(core.List<core.int> x) m() => null;
+''');
+ ClassMember member = parser.parseClassMember('C');
+ listener.assertNoErrors();
+ expect(member, new isInstanceOf<MethodDeclaration>());
+ expect((member as MethodDeclaration).body,
+ new isInstanceOf<ExpressionFunctionBody>());
+ }
+
void test_parseCombinator_hide() {
createParser('hide a;');
Combinator combinator = parser.parseCombinator();
@@ -10627,6 +10665,49 @@
expect(reference.offset, 15);
}
+ void test_parseCompilationUnitMember_function_gftReturnType() {
+ createParser('''
+void Function<A>(core.List<core.int> x) f() => null;
+''');
+ CompilationUnit unit = parser.parseCompilationUnit2();
+ listener.assertNoErrors();
+ expect(unit, isNotNull);
+ expect(unit.declarations, hasLength(1));
+ }
+
+ void test_parseCompilationUnitMember_function_noReturnType() {
+ createParser('''
+Function<A>(core.List<core.int> x) f() => null;
+''');
+ CompilationUnit unit = parser.parseCompilationUnit2();
+ listener.assertNoErrors();
+ expect(unit, isNotNull);
+ expect(unit.declarations, hasLength(1));
+ }
+
+ void test_parseCompilationUnitMember_variable_gftType_gftReturnType() {
+ createParser('''
+Function(int) Function(String) v;
+''');
+ CompilationUnit unit = parser.parseCompilationUnit2();
+ listener.assertNoErrors();
+ expect(unit, isNotNull);
+ expect(unit.declarations, hasLength(1));
+ TopLevelVariableDeclaration declaration =
+ unit.declarations[0] as TopLevelVariableDeclaration;
+ expect(declaration.variables.type, new isInstanceOf<GenericFunctionType>());
+ }
+
+ void test_parseCompilationUnitMember_variable_gftType_noReturnType() {
+ createParser('''
+Function(int, String) v;
+''');
+ CompilationUnit unit = parser.parseCompilationUnit2();
+ listener.assertNoErrors();
+ expect(unit, isNotNull);
+ expect(unit.declarations, hasLength(1));
+ }
+
void test_parseConfiguration_noOperator_dottedIdentifier() {
createParser("if (a.b) 'c.dart'");
Configuration configuration = parser.parseConfiguration();
@@ -11239,6 +11320,13 @@
expect(modifiers.varKeyword, isNotNull);
}
+ void test_parseNonLabeledStatement_localFunction_gftReturnType() {
+ createParser('int Function(int) f(String s) => null;');
+ Statement statement = parser.parseNonLabeledStatement();
+ expectNotNullIfNoErrors(statement);
+ listener.assertNoErrors();
+ }
+
void test_parseNonLabeledStatement_variableDeclaration_final_namedFunction() {
createParser('final int Function = 0;');
Statement statement = parser.parseNonLabeledStatement();
@@ -11246,6 +11334,61 @@
listener.assertNoErrors();
}
+ void test_parseNonLabeledStatement_variableDeclaration_gftType() {
+ createParser('int Function(int) v;');
+ Statement statement = parser.parseNonLabeledStatement();
+ expectNotNullIfNoErrors(statement);
+ listener.assertNoErrors();
+ }
+
+ void
+ test_parseNonLabeledStatement_variableDeclaration_gftType_functionReturnType() {
+ createParser(
+ 'Function Function(int x1, {Function x}) Function<B extends core.int>(int x) l771;');
+ Statement statement = parser.parseNonLabeledStatement();
+ expectNotNullIfNoErrors(statement);
+ listener.assertNoErrors();
+ }
+
+ void
+ test_parseNonLabeledStatement_variableDeclaration_gftType_gftReturnType() {
+ createParser('Function(int) Function(int) v;');
+ Statement statement = parser.parseNonLabeledStatement();
+ expectNotNullIfNoErrors(statement);
+ listener.assertNoErrors();
+ }
+
+ void
+ test_parseNonLabeledStatement_variableDeclaration_gftType_gftReturnType2() {
+ createParser('int Function(int) Function(int) v;');
+ Statement statement = parser.parseNonLabeledStatement();
+ expectNotNullIfNoErrors(statement);
+ listener.assertNoErrors();
+ }
+
+ void
+ test_parseNonLabeledStatement_variableDeclaration_gftType_noReturnType() {
+ createParser('Function(int) v;');
+ Statement statement = parser.parseNonLabeledStatement();
+ expectNotNullIfNoErrors(statement);
+ listener.assertNoErrors();
+ }
+
+ void test_parseNonLabeledStatement_variableDeclaration_gftType_returnType() {
+ createParser('int Function<T>() v;');
+ Statement statement = parser.parseNonLabeledStatement();
+ expectNotNullIfNoErrors(statement);
+ listener.assertNoErrors();
+ }
+
+ void
+ test_parseNonLabeledStatement_variableDeclaration_gftType_voidReturnType() {
+ createParser('void Function() v;');
+ Statement statement = parser.parseNonLabeledStatement();
+ expectNotNullIfNoErrors(statement);
+ listener.assertNoErrors();
+ }
+
void test_parseOptionalReturnType() {
// TODO(brianwilkerson) Implement tests for this method.
}
@@ -11302,6 +11445,34 @@
expect(typeName.typeArguments, isNull);
}
+ void test_parseStatement_function_gftReturnType() {
+ createParser('''
+void Function<A>(core.List<core.int> x) m() => null;
+''');
+ Statement statement = parser.parseStatement2();
+ expect(statement, new isInstanceOf<FunctionDeclarationStatement>());
+ expect(
+ (statement as FunctionDeclarationStatement)
+ .functionDeclaration
+ .functionExpression
+ .body,
+ new isInstanceOf<ExpressionFunctionBody>());
+ }
+
+ void test_parseStatement_function_noReturnType() {
+ createParser('''
+Function<A>(core.List<core.int> x) m() => null;
+''');
+ Statement statement = parser.parseStatement2();
+ expect(statement, new isInstanceOf<FunctionDeclarationStatement>());
+ expect(
+ (statement as FunctionDeclarationStatement)
+ .functionDeclaration
+ .functionExpression
+ .body,
+ new isInstanceOf<ExpressionFunctionBody>());
+ }
+
void test_parseStatements_multiple() {
List<Statement> statements = parseStatements("return; return;", 2);
expect(statements, hasLength(2));
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 5f6ee00..7aefb1f 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -442,13 +442,26 @@
writeDocumentation(e);
writeMetadata(e, '', '\n');
- buffer.write('typedef ');
- writeType2(e.returnType);
+ if (e is GenericTypeAliasElement) {
+ buffer.write('typedef ');
+ writeName(e);
+ writeTypeParameterElements(e.typeParameters);
- writeName(e);
+ buffer.write(' = ');
- writeTypeParameterElements(e.typeParameters);
- writeParameterElements(e.parameters);
+ writeType(e.function.returnType);
+ buffer.write(' Function');
+ writeTypeParameterElements(e.function.typeParameters);
+ writeParameterElements(e.function.parameters);
+ } else {
+ buffer.write('typedef ');
+ writeType2(e.returnType);
+
+ writeName(e);
+
+ writeTypeParameterElements(e.typeParameters);
+ writeParameterElements(e.parameters);
+ }
buffer.writeln(';');
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 38455bc..aec154d 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -8542,6 +8542,82 @@
}
}
+ test_genericFunction_asFunctionReturnType() {
+ shouldCompareLibraryElements = false;
+ var library = checkLibrary(r'''
+int Function(int a, String b) f() => null;
+''');
+ checkElementText(
+ library,
+ r'''
+(int, String) → int f() {}
+''');
+ }
+
+ test_genericFunction_asFunctionTypedParameterReturnType() {
+ shouldCompareLibraryElements = false;
+ var library = checkLibrary(r'''
+void f(int Function(int a, String b) p(num c)) => null;
+''');
+ checkElementText(
+ library,
+ r'''
+void f((num) → (int, String) → int p) {}
+''');
+ }
+
+ test_genericFunction_asGenericFunctionReturnType() {
+ shouldCompareLibraryElements = false;
+ var library = checkLibrary(r'''
+typedef F = void Function(String a) Function(int b);
+''');
+ checkElementText(
+ library,
+ r'''
+typedef F = (String) → void Function(int b);
+''');
+ }
+
+ test_genericFunction_asMethodReturnType() {
+ shouldCompareLibraryElements = false;
+ var library = checkLibrary(r'''
+class C {
+ int Function(int a, String b) m() => null;
+}
+''');
+ checkElementText(
+ library,
+ r'''
+class C {
+ (int, String) → int m() {}
+}
+''');
+ }
+
+ test_genericFunction_asParameterType() {
+ shouldCompareLibraryElements = false;
+ var library = checkLibrary(r'''
+void f(int Function(int a, String b) p) => null;
+''');
+ checkElementText(
+ library,
+ r'''
+void f((int, String) → int p) {}
+''');
+ }
+
+ test_genericFunction_asTopLevelVariableType() {
+ shouldCompareLibraryElements = false;
+ var library = checkLibrary(r'''
+int Function(int a, String b) v;
+''');
+ checkElementText(
+ library,
+ r'''
+(int, String) → int v;
+''');
+ }
+
test_getElement_constructor_named() {
String text = 'class C { C.named(); }';
Source source = addLibrarySource('/test.dart', text);
@@ -13860,8 +13936,50 @@
}
test_typedef_generic() {
- checkLibrary(
- 'typedef F<T> = Function<S>(List<S> list, Function<A>(A), T);');
+ var library = checkLibrary(
+ 'typedef F<T> = int Function<S>(List<S> list, num Function<A>(A), T);');
+ if (isStrongMode) {
+ checkElementText(
+ library,
+ r'''
+typedef F<T> = int Function<S>(List<S> list, <A>(A) → num , T );
+''');
+ } else {
+ checkElementText(
+ library,
+ r'''
+typedef F<T> = int Function<S>(List<S> list, <A>(A) → num , T );
+''');
+ }
+ }
+
+ test_typedef_generic_asFieldType() {
+ shouldCompareLibraryElements = false;
+ var library = checkLibrary(r'''
+typedef Foo<S> = S Function<T>(T x);
+class A {
+ Foo<int> f;
+}
+''');
+ if (isStrongMode) {
+ checkElementText(
+ library,
+ r'''
+typedef Foo<S> = S Function<T>(T x);
+class A {
+ <T>(T) → int f;
+}
+''');
+ } else {
+ checkElementText(
+ library,
+ r'''
+typedef Foo<S> = S Function<T>(T x);
+class A {
+ <T>(T) → int f;
+}
+''');
+ }
}
test_typedef_parameter_parameters() {
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index a765d6c..b76f860 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -6455,6 +6455,14 @@
linked.exportNames[0], absUri('/a.dart'), 'F', ReferenceKind.typedef);
}
+ test_export_typedef_genericFunction() {
+ addNamedSource('/a.dart', 'typedef F<S> = S Function<T>(T x);');
+ serializeLibraryText('export "a.dart";');
+ expect(linked.exportNames, hasLength(1));
+ checkExportName(linked.exportNames[0], absUri('/a.dart'), 'F',
+ ReferenceKind.genericFunctionTypedef);
+ }
+
test_export_uri() {
addNamedSource('/a.dart', 'library my.lib;');
String uriString = '"a.dart"';
@@ -10135,6 +10143,60 @@
checkDocumentationComment(typedef.documentationComment, text);
}
+ test_typedef_genericFunction_reference() {
+ EntityRef typeRef = serializeTypeText('F',
+ otherDeclarations: 'typedef F<S> = S Function<T>(T x);');
+ checkTypeRef(typeRef, null, 'F',
+ numTypeParameters: 1,
+ expectedKind: ReferenceKind.genericFunctionTypedef);
+ }
+
+ test_typedef_genericFunction_typeNames() {
+ UnlinkedTypedef typedef =
+ serializeTypedefText('typedef F<S> = S Function(int x, String y);');
+ expect(typedef.style, TypedefStyle.genericFunctionType);
+ expect(typedef.typeParameters, hasLength(1));
+ expect(typedef.typeParameters[0].name, 'S');
+ expect(typedef.parameters, isEmpty);
+
+ EntityRef genericFunction = typedef.returnType;
+ expect(genericFunction.entityKind, EntityRefKind.genericFunctionType);
+ expect(genericFunction.typeParameters, isEmpty);
+
+ List<UnlinkedParam> functionParameters = genericFunction.syntheticParams;
+ expect(functionParameters, hasLength(2));
+ expect(functionParameters[0].name, 'x');
+ expect(functionParameters[1].name, 'y');
+ checkLinkedTypeRef(functionParameters[0].type, 'dart:core', 'int');
+ checkLinkedTypeRef(functionParameters[1].type, 'dart:core', 'String');
+
+ checkParamTypeRef(genericFunction.syntheticReturnType, 1);
+ }
+
+ test_typedef_genericFunction_typeParameters() {
+ UnlinkedTypedef typedef =
+ serializeTypedefText('typedef F<S> = S Function<T1, T2>(T1 x, T2 y);');
+ expect(typedef.style, TypedefStyle.genericFunctionType);
+ expect(typedef.typeParameters, hasLength(1));
+ expect(typedef.typeParameters[0].name, 'S');
+ expect(typedef.parameters, isEmpty);
+
+ EntityRef genericFunction = typedef.returnType;
+ expect(genericFunction.entityKind, EntityRefKind.genericFunctionType);
+
+ expect(genericFunction.typeParameters, hasLength(2));
+ expect(genericFunction.typeParameters[0].name, 'T1');
+ expect(genericFunction.typeParameters[1].name, 'T2');
+
+ expect(genericFunction.syntheticParams, hasLength(2));
+ expect(genericFunction.syntheticParams[0].name, 'x');
+ expect(genericFunction.syntheticParams[1].name, 'y');
+ checkParamTypeRef(genericFunction.syntheticParams[0].type, 2);
+ checkParamTypeRef(genericFunction.syntheticParams[1].type, 1);
+
+ checkParamTypeRef(genericFunction.syntheticReturnType, 3);
+ }
+
test_typedef_name() {
String text = 'typedef F();';
UnlinkedTypedef type = serializeTypedefText(text);
diff --git a/runtime/bin/secure_socket_boringssl.cc b/runtime/bin/secure_socket_boringssl.cc
index f2df95d..a3740a8 100644
--- a/runtime/bin/secure_socket_boringssl.cc
+++ b/runtime/bin/secure_socket_boringssl.cc
@@ -83,24 +83,26 @@
// Get the error messages from BoringSSL, and put them in buffer as a
// null-terminated string.
static void FetchErrorString(const SSL* ssl, TextBuffer* text_buffer) {
- uint32_t error = 0;
- const char* path = NULL;
- int line = -1;
const char* sep = File::PathSeparator();
- do {
- error = ERR_get_error_line(&path, &line);
- const char* file = strrchr(path, sep[0]);
- path = file ? file + 1 : path;
+ while (true) {
+ const char* path = NULL;
+ int line = -1;
+ uint32_t error = ERR_get_error_line(&path, &line);
+ if (error == 0) {
+ break;
+ }
+ text_buffer->Printf("\n\t%s", ERR_reason_error_string(error));
if ((ssl != NULL) && (ERR_GET_LIB(error) == ERR_LIB_SSL) &&
(ERR_GET_REASON(error) == SSL_R_CERTIFICATE_VERIFY_FAILED)) {
intptr_t result = SSL_get_verify_result(ssl);
- text_buffer->Printf("\n\t%s: %s (%s:%d)", ERR_reason_error_string(error),
- X509_verify_cert_error_string(result), path, line);
- } else if (error != 0) {
- text_buffer->Printf("\n\t%s (%s:%d)", ERR_reason_error_string(error),
- path, line);
+ text_buffer->Printf(": %s", X509_verify_cert_error_string(result));
}
- } while (error != 0);
+ if ((path != NULL) && (line >= 0)) {
+ const char* file = strrchr(path, sep[0]);
+ path = file ? file + 1 : path;
+ text_buffer->Printf("(%s:%d)", path, line);
+ }
+ }
}
diff --git a/tools/VERSION b/tools/VERSION
index e09399d..f52e40f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
MINOR 23
PATCH 0
PRERELEASE 11
-PRERELEASE_PATCH 7
+PRERELEASE_PATCH 8