Skip to content

Commit e4999a6

Browse files
committed
Add support for the new function-type syntax.
Fixes #27967 BUG= http://dartbug.com/27967 [email protected] Committed: 85227ba Reverted: f5fc210 Review-Url: https://codereview.chromium.org/2567133002 .
1 parent 511e710 commit e4999a6

35 files changed

+76630
-140
lines changed

pkg/compiler/lib/src/common/resolution.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ library dart2js.common.resolution;
66

77
import '../common.dart';
88
import '../compile_time_constants.dart';
9-
import '../compiler.dart' show Compiler;
109
import '../constants/expressions.dart' show ConstantExpression;
1110
import '../constants/values.dart' show ConstantValue;
1211
import '../core_types.dart' show CommonElements;

pkg/compiler/lib/src/elements/elements.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,9 @@ abstract class FormalElement extends Element
11131113
FunctionTypedElement get functionDeclaration;
11141114

11151115
VariableDefinitions get node;
1116+
1117+
/// Whether the parameter is unnamed in a function type.
1118+
bool get isUnnamed;
11161119
}
11171120

11181121
/// A formal parameter of a function or constructor.

pkg/compiler/lib/src/elements/modelx.dart

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1345,7 +1345,7 @@ class TypedefElementX extends ElementX
13451345
ResolutionTypedefType computeType(Resolution resolution) {
13461346
if (thisTypeCache != null) return thisTypeCache;
13471347
Typedef node = parseNode(resolution.parsingContext);
1348-
setThisAndRawTypes(createTypeVariables(node.typeParameters));
1348+
setThisAndRawTypes(createTypeVariables(node.templateParameters));
13491349
ensureResolved(resolution);
13501350
return thisTypeCache;
13511351
}
@@ -1743,6 +1743,15 @@ class FormalElementX extends ElementX
17431743
: this.identifier = identifier,
17441744
super(identifier.source, elementKind, enclosingElement);
17451745

1746+
FormalElementX.unnamed(ElementKind elementKind,
1747+
FunctionTypedElement enclosingElement,
1748+
this.definitions)
1749+
: this.identifier = null,
1750+
super("<unnamed>", elementKind, enclosingElement);
1751+
1752+
/// Whether this is an unnamed parameter in a Function type.
1753+
bool get isUnnamed => identifier == null;
1754+
17461755
FunctionTypedElement get functionDeclaration => enclosingElement;
17471756

17481757
Modifiers get modifiers => definitions.modifiers;

pkg/compiler/lib/src/elements/resolution_types.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,16 @@ class ResolutionFunctionType extends ResolutionDartType
642642
optionalParameterTypes, namedParameters, namedParameterTypes);
643643
}
644644

645+
factory ResolutionFunctionType.generalized(
646+
ResolutionDartType returnType,
647+
List<ResolutionDartType> parameterTypes,
648+
List<ResolutionDartType> optionalParameterTypes,
649+
List<String> namedParameters,
650+
List<ResolutionDartType> namedParameterTypes) {
651+
return new ResolutionFunctionType.internal(null, returnType, parameterTypes,
652+
optionalParameterTypes, namedParameters, namedParameterTypes);
653+
}
654+
645655
ResolutionFunctionType.internal(FunctionTypedElement this.element,
646656
[ResolutionDartType returnType = const ResolutionDynamicType(),
647657
List<ResolutionDartType> parameterTypes = const <ResolutionDartType>[],

pkg/compiler/lib/src/js_backend/no_such_method_registry.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ class NoSuchMethodRegistry {
219219
}
220220
if (expr is Send && expr.isTypeCast) {
221221
Send sendExpr = expr;
222-
var typeName = sendExpr.typeAnnotationFromIsCheckOrCast.typeName;
222+
var typeAnnotation = sendExpr.typeAnnotationFromIsCheckOrCast;
223+
var typeName = typeAnnotation.asNominalTypeAnnotation()?.typeName;
223224
if (typeName is Identifier && typeName.source == "dynamic") {
224225
expr = sendExpr.receiver;
225226
}

pkg/compiler/lib/src/kernel/kernel_visitor.dart

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ import '../tree/tree.dart'
104104
ForIn,
105105
FunctionDeclaration,
106106
FunctionExpression,
107+
FunctionTypeAnnotation,
107108
Identifier,
108109
If,
109110
Label,
@@ -122,6 +123,7 @@ import '../tree/tree.dart'
122123
NewExpression,
123124
Node,
124125
NodeList,
126+
NominalTypeAnnotation,
125127
Operator,
126128
ParenthesizedExpression,
127129
RedirectingFactoryBody,
@@ -1087,14 +1089,28 @@ class KernelVisitor extends Object
10871089

10881090
@override
10891091
visitTypeAnnotation(TypeAnnotation node) {
1090-
// Shouldn't be called, as the resolver have already resolved types and
1092+
// Shouldn't be called, as the resolver has already resolved types and
10911093
// created [DartType] objects.
10921094
return internalError(node, "TypeAnnotation");
10931095
}
10941096

1097+
@override
1098+
visitNominalTypeAnnotation(NominalTypeAnnotation node) {
1099+
// Shouldn't be called, as the resolver has already resolved types and
1100+
// created [DartType] objects.
1101+
return internalError(node, "NominalTypeAnnotation");
1102+
}
1103+
1104+
@override
1105+
visitFunctionTypeAnnotation(FunctionTypeAnnotation node) {
1106+
// Shouldn't be called, as the resolver has already resolved types and
1107+
// created [DartType] objects.
1108+
return internalError(node, "FunctionTypeAnnotation");
1109+
}
1110+
10951111
@override
10961112
visitTypeVariable(TypeVariable node) {
1097-
// Shouldn't be called, as the resolver have already resolved types and
1113+
// Shouldn't be called, as the resolver has already resolved types and
10981114
// created [DartType] objects.
10991115
return internalError(node, "TypeVariable");
11001116
}

pkg/compiler/lib/src/native/behavior.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ class NativeBehavior {
257257
/// Each tag kind (including the 'type-tag's) can only occur once in the
258258
/// sequence.
259259
///
260-
/// [specString] is the specification string, [resolveType] resolves named
260+
/// [specString] is the specification string, [lookupType] resolves named
261261
/// types into type values, [typesReturned] and [typesInstantiated] collects
262262
/// the types defined by the specification string, and [objectType] and
263263
/// [nullType] define the types for `Object` and `Null`, respectively. The

pkg/compiler/lib/src/parser/element_listener.dart

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -260,10 +260,17 @@ class ElementListener extends Listener {
260260
}
261261
}
262262

263-
void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
264-
popNode(); // TODO(karlklose): do not throw away typeVariables.
265-
Identifier name = popNode();
266-
popNode(); // returnType
263+
void endTypedef(Token typedefKeyword, Token equals, Token endToken) {
264+
Identifier name;
265+
if (equals == null) {
266+
popNode(); // TODO(karlklose): do not throw away typeVariables.
267+
name = popNode();
268+
popNode(); // returnType
269+
} else {
270+
popNode(); // Function type.
271+
popNode(); // TODO(karlklose): do not throw away typeVariables.
272+
name = popNode();
273+
}
267274
pushElement(new PartialTypedefElement(
268275
name.source, compilationUnitElement, typedefKeyword, endToken));
269276
rejectBuiltInIdentifier(name);
@@ -294,12 +301,12 @@ class ElementListener extends Listener {
294301

295302
void endMixinApplication() {
296303
NodeList mixins = popNode();
297-
TypeAnnotation superclass = popNode();
304+
NominalTypeAnnotation superclass = popNode();
298305
pushNode(new MixinApplication(superclass, mixins));
299306
}
300307

301308
void handleVoidKeyword(Token token) {
302-
pushNode(new TypeAnnotation(new Identifier(token), null));
309+
pushNode(new NominalTypeAnnotation(new Identifier(token), null));
303310
}
304311

305312
void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
@@ -366,7 +373,7 @@ class ElementListener extends Listener {
366373
}
367374

368375
void endTypeVariable(Token token, Token extendsOrSuper) {
369-
TypeAnnotation bound = popNode();
376+
NominalTypeAnnotation bound = popNode();
370377
Identifier name = popNode();
371378
pushNode(new TypeVariable(name, extendsOrSuper, bound));
372379
rejectBuiltInIdentifier(name);
@@ -391,7 +398,17 @@ class ElementListener extends Listener {
391398
void endType(Token beginToken, Token endToken) {
392399
NodeList typeArguments = popNode();
393400
Expression typeName = popNode();
394-
pushNode(new TypeAnnotation(typeName, typeArguments));
401+
pushNode(new NominalTypeAnnotation(typeName, typeArguments));
402+
}
403+
404+
void handleNoName(Token token) {
405+
pushNode(null);
406+
}
407+
408+
void endFunctionType(Token functionToken, Token endToken) {
409+
popNode(); // Type parameters.
410+
popNode(); // Return type.
411+
pushNode(null);
395412
}
396413

397414
void handleParenthesizedExpression(BeginGroupToken token) {

pkg/compiler/lib/src/parser/listener.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,9 @@ class Listener {
130130

131131
void endFunctionName(Token token) {}
132132

133-
void beginFunctionTypeAlias(Token token) {}
133+
void beginTypedef(Token token) {}
134134

135-
void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {}
135+
void endTypedef(Token typedefKeyword, Token equals, Token endToken) {}
136136

137137
void beginMixinApplication(Token token) {}
138138

@@ -295,6 +295,10 @@ class Listener {
295295

296296
void endType(Token beginToken, Token endToken) {}
297297

298+
void handleNoName(Token token) {}
299+
300+
void endFunctionType(Token functionToken, Token endToken) {}
301+
298302
void beginTypeArguments(Token token) {}
299303

300304
void endTypeArguments(int count, Token beginToken, Token endToken) {}

pkg/compiler/lib/src/parser/node_listener.dart

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import '../tokens/token.dart' show ErrorToken, StringToken, Token;
1212
import '../tree/tree.dart';
1313
import '../util/util.dart' show Link;
1414
import 'element_listener.dart' show ElementListener, ScannerOptions;
15-
import 'partial_elements.dart' show PartialFunctionElement;
1615

1716
class NodeListener extends ElementListener {
1817
NodeListener(ScannerOptions scannerOptions, DiagnosticReporter reporter,
@@ -115,13 +114,58 @@ class NodeListener extends ElementListener {
115114
pushNode(makeNodeList(count, null, null, '\n'));
116115
}
117116

118-
void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
117+
void endTypedef(Token typedefKeyword, Token equals, Token endToken) {
118+
bool isGeneralizedTypeAlias;
119+
NodeList templateParameters;
120+
TypeAnnotation returnType;
121+
Identifier name;
122+
NodeList typeParameters;
123+
NodeList formals;
124+
if (equals == null) {
125+
isGeneralizedTypeAlias = false;
126+
formals = popNode();
127+
templateParameters = popNode();
128+
name = popNode();
129+
returnType = popNode();
130+
} else {
131+
// TODO(floitsch): keep using the `FunctionTypeAnnotation' node.
132+
isGeneralizedTypeAlias = true;
133+
Node type = popNode();
134+
if (type.asFunctionTypeAnnotation() == null) {
135+
// TODO(floitsch): The parser should diagnose this problem, not
136+
// this listener.
137+
// However, this problem goes away, when we allow aliases for
138+
// non-function types too.
139+
reportFatalError(type, 'Expected a function type.');
140+
}
141+
FunctionTypeAnnotation functionType = type;
142+
templateParameters = popNode();
143+
name = popNode();
144+
returnType = functionType.returnType;
145+
typeParameters = functionType.typeParameters;
146+
formals = functionType.formals;
147+
}
148+
pushNode(new Typedef(
149+
isGeneralizedTypeAlias,
150+
templateParameters,
151+
returnType,
152+
name,
153+
typeParameters,
154+
formals,
155+
typedefKeyword,
156+
endToken));
157+
}
158+
159+
void handleNoName(Token token) {
160+
pushNode(null);
161+
}
162+
163+
void endFunctionType(Token functionToken, Token endToken) {
119164
NodeList formals = popNode();
120165
NodeList typeParameters = popNode();
121-
Identifier name = popNode();
122166
TypeAnnotation returnType = popNode();
123-
pushNode(new Typedef(
124-
returnType, name, typeParameters, formals, typedefKeyword, endToken));
167+
pushNode(new FunctionTypeAnnotation(
168+
returnType, functionToken, typeParameters, formals));
125169
}
126170

127171
void endNamedMixinApplication(
@@ -206,7 +250,7 @@ class NodeListener extends ElementListener {
206250
NodeList typeArguments = popNode();
207251
Node classReference = popNode();
208252
if (typeArguments != null) {
209-
classReference = new TypeAnnotation(classReference, typeArguments);
253+
classReference = new NominalTypeAnnotation(classReference, typeArguments);
210254
} else {
211255
Identifier identifier = classReference.asIdentifier();
212256
Send send = classReference.asSend();
@@ -791,7 +835,7 @@ class NodeListener extends ElementListener {
791835
NodeList typeArguments = popNode();
792836
Node receiver = popNode();
793837
if (typeArguments != null) {
794-
receiver = new TypeAnnotation(receiver, typeArguments);
838+
receiver = new NominalTypeAnnotation(receiver, typeArguments);
795839
recoverableError(typeArguments, 'Type arguments are not allowed here.');
796840
} else {
797841
Identifier identifier = receiver.asIdentifier();

0 commit comments

Comments
 (0)