OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart2js.resolution.signatures; | 5 library dart2js.resolution.signatures; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/resolution.dart'; | 8 import '../common/resolution.dart'; |
9 import '../elements/resolution_types.dart'; | 9 import '../elements/resolution_types.dart'; |
10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 reporter.reportErrorMessage(node, MessageKind.FORMAL_DECLARED_CONST); | 86 reporter.reportErrorMessage(node, MessageKind.FORMAL_DECLARED_CONST); |
87 } | 87 } |
88 if (node.modifiers.isStatic) { | 88 if (node.modifiers.isStatic) { |
89 reporter.reportErrorMessage(node, MessageKind.FORMAL_DECLARED_STATIC); | 89 reporter.reportErrorMessage(node, MessageKind.FORMAL_DECLARED_STATIC); |
90 } | 90 } |
91 | 91 |
92 if (currentDefinitions != null) { | 92 if (currentDefinitions != null) { |
93 reporter.internalError(node, 'function type parameters not supported'); | 93 reporter.internalError(node, 'function type parameters not supported'); |
94 } | 94 } |
95 currentDefinitions = node; | 95 currentDefinitions = node; |
96 FormalElementX element = definition.accept(this); | 96 FormalElementX element = definition == null |
| 97 ? createUnnamedParameter() // This happens in function types. |
| 98 : definition.accept(this); |
97 if (currentDefinitions.metadata != null) { | 99 if (currentDefinitions.metadata != null) { |
98 element.metadataInternal = | 100 element.metadataInternal = |
99 resolution.resolver.resolveMetadata(element, node); | 101 resolution.resolver.resolveMetadata(element, node); |
100 } | 102 } |
101 currentDefinitions = null; | 103 currentDefinitions = null; |
102 return element; | 104 return element; |
103 } | 105 } |
104 | 106 |
105 void validateName(Identifier node) { | 107 void validateName(Identifier node) { |
106 if (isOptionalParameter && | 108 if (isOptionalParameter && |
107 optionalParametersAreNamed && | 109 optionalParametersAreNamed && |
108 Name.isPrivateName(node.source)) { | 110 Name.isPrivateName(node.source)) { |
109 reporter.reportErrorMessage(node, MessageKind.PRIVATE_NAMED_PARAMETER); | 111 reporter.reportErrorMessage(node, MessageKind.PRIVATE_NAMED_PARAMETER); |
110 } | 112 } |
111 } | 113 } |
112 | 114 |
113 void computeParameterType(FormalElementX element, | 115 void computeParameterType(FormalElementX element, |
114 [VariableElement fieldElement]) { | 116 [VariableElement fieldElement]) { |
115 void computeFunctionType(FunctionExpression functionExpression) { | 117 // Function-type as in `foo(int bar(String x))` |
| 118 void computeInlineFunctionType(FunctionExpression functionExpression) { |
116 FunctionSignature functionSignature = SignatureResolver.analyze( | 119 FunctionSignature functionSignature = SignatureResolver.analyze( |
117 resolution, | 120 resolution, |
118 scope, | 121 scope, |
119 functionExpression.typeVariables, | 122 functionExpression.typeVariables, |
120 functionExpression.parameters, | 123 functionExpression.parameters, |
121 functionExpression.returnType, | 124 functionExpression.returnType, |
122 element, | 125 element, |
123 registry, | 126 registry, |
124 defaultValuesError: MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT); | 127 defaultValuesError: MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT); |
125 element.functionSignature = functionSignature; | 128 element.functionSignature = functionSignature; |
126 } | 129 } |
127 | 130 |
128 if (currentDefinitions.type != null) { | 131 if (currentDefinitions.type != null) { |
129 element.typeCache = resolveTypeAnnotation(currentDefinitions.type); | 132 element.typeCache = resolveTypeAnnotation(currentDefinitions.type); |
130 } else { | 133 } else { |
131 // Is node.definitions exactly one FunctionExpression? | 134 // Is node.definitions exactly one FunctionExpression? |
132 Link<Node> link = currentDefinitions.definitions.nodes; | 135 Link<Node> link = currentDefinitions.definitions.nodes; |
133 assert(invariant(currentDefinitions, !link.isEmpty)); | 136 assert(invariant(currentDefinitions, !link.isEmpty)); |
134 assert(invariant(currentDefinitions, link.tail.isEmpty)); | 137 assert(invariant(currentDefinitions, link.tail.isEmpty)); |
135 if (link.head.asFunctionExpression() != null) { | 138 if (link.head.asFunctionExpression() != null) { |
136 // Inline function typed parameter, like `void m(int f(String s))`. | 139 // Inline function typed parameter, like `void m(int f(String s))`. |
137 computeFunctionType(link.head); | 140 computeInlineFunctionType(link.head); |
138 } else if (link.head.asSend() != null && | 141 } else if (link.head.asSend() != null && |
139 link.head.asSend().selector.asFunctionExpression() != null) { | 142 link.head.asSend().selector.asFunctionExpression() != null) { |
140 // Inline function typed initializing formal or | 143 // Inline function typed initializing formal or |
141 // parameter with default value, like `C(int this.f(String s))` or | 144 // parameter with default value, like `C(int this.f(String s))` or |
142 // `void m([int f(String s) = null])`. | 145 // `void m([int f(String s) = null])`. |
143 computeFunctionType(link.head.asSend().selector.asFunctionExpression()); | 146 computeInlineFunctionType( |
| 147 link.head.asSend().selector.asFunctionExpression()); |
144 } else { | 148 } else { |
145 assert(invariant(currentDefinitions, | 149 assert(invariant(currentDefinitions, |
146 link.head.asIdentifier() != null || link.head.asSend() != null)); | 150 link.head.asIdentifier() != null || link.head.asSend() != null)); |
147 if (fieldElement != null) { | 151 if (fieldElement != null) { |
148 element.typeCache = fieldElement.computeType(resolution); | 152 element.typeCache = fieldElement.computeType(resolution); |
149 } else { | 153 } else { |
150 element.typeCache = const ResolutionDynamicType(); | 154 element.typeCache = const ResolutionDynamicType(); |
151 } | 155 } |
152 } | 156 } |
153 } | 157 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 enclosingElement, currentDefinitions, name, initializer, | 194 enclosingElement, currentDefinitions, name, initializer, |
191 isOptional: isOptionalParameter, isNamed: optionalParametersAreNamed); | 195 isOptional: isOptionalParameter, isNamed: optionalParametersAreNamed); |
192 } else { | 196 } else { |
193 parameter = new FormalElementX( | 197 parameter = new FormalElementX( |
194 ElementKind.PARAMETER, enclosingElement, currentDefinitions, name); | 198 ElementKind.PARAMETER, enclosingElement, currentDefinitions, name); |
195 } | 199 } |
196 computeParameterType(parameter); | 200 computeParameterType(parameter); |
197 return parameter; | 201 return parameter; |
198 } | 202 } |
199 | 203 |
| 204 FormalElementX createUnnamedParameter() { |
| 205 FormalElementX parameter; |
| 206 assert(!createRealParameters); |
| 207 parameter = new FormalElementX.unnamed( |
| 208 ElementKind.PARAMETER, enclosingElement, currentDefinitions); |
| 209 computeParameterType(parameter); |
| 210 return parameter; |
| 211 } |
| 212 |
200 InitializingFormalElementX createFieldParameter( | 213 InitializingFormalElementX createFieldParameter( |
201 Send node, Expression initializer) { | 214 Send node, Expression initializer) { |
202 InitializingFormalElementX element; | 215 InitializingFormalElementX element; |
203 Identifier receiver = node.receiver.asIdentifier(); | 216 Identifier receiver = node.receiver.asIdentifier(); |
204 if (receiver == null || !receiver.isThis()) { | 217 if (receiver == null || !receiver.isThis()) { |
205 reporter.reportErrorMessage(node, MessageKind.INVALID_PARAMETER); | 218 reporter.reportErrorMessage(node, MessageKind.INVALID_PARAMETER); |
206 return new ErroneousInitializingFormalElementX( | 219 return new ErroneousInitializingFormalElementX( |
207 getParameterName(node), enclosingElement); | 220 getParameterName(node), enclosingElement); |
208 } else { | 221 } else { |
209 if (!enclosingElement.isGenerativeConstructor) { | 222 if (!enclosingElement.isGenerativeConstructor) { |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 } else { | 392 } else { |
380 AsyncMarker asyncMarker = AsyncMarker.SYNC; | 393 AsyncMarker asyncMarker = AsyncMarker.SYNC; |
381 if (isFunctionExpression) { | 394 if (isFunctionExpression) { |
382 // Use async marker to determine the return type of function | 395 // Use async marker to determine the return type of function |
383 // expressions. | 396 // expressions. |
384 FunctionElement function = element; | 397 FunctionElement function = element; |
385 asyncMarker = function.asyncMarker; | 398 asyncMarker = function.asyncMarker; |
386 } | 399 } |
387 switch (asyncMarker) { | 400 switch (asyncMarker) { |
388 case AsyncMarker.SYNC: | 401 case AsyncMarker.SYNC: |
389 returnType = visitor.resolveReturnType(returnNode); | 402 returnType = visitor.resolveTypeAnnotation(returnNode); |
390 break; | 403 break; |
391 case AsyncMarker.SYNC_STAR: | 404 case AsyncMarker.SYNC_STAR: |
392 ResolutionInterfaceType iterableType = | 405 ResolutionInterfaceType iterableType = |
393 resolution.commonElements.iterableType(); | 406 resolution.commonElements.iterableType(); |
394 returnType = iterableType; | 407 returnType = iterableType; |
395 break; | 408 break; |
396 case AsyncMarker.ASYNC: | 409 case AsyncMarker.ASYNC: |
397 ResolutionInterfaceType futureType = | 410 ResolutionInterfaceType futureType = |
398 resolution.commonElements.futureType(); | 411 resolution.commonElements.futureType(); |
399 returnType = futureType; | 412 returnType = futureType; |
(...skipping 19 matching lines...) Expand all Loading... |
419 for (FormalElement parameter in parameters) { | 432 for (FormalElement parameter in parameters) { |
420 parameterTypes.addLast(parameter.type); | 433 parameterTypes.addLast(parameter.type); |
421 } | 434 } |
422 List<ResolutionDartType> optionalParameterTypes = | 435 List<ResolutionDartType> optionalParameterTypes = |
423 const <ResolutionDartType>[]; | 436 const <ResolutionDartType>[]; |
424 List<String> namedParameters = const <String>[]; | 437 List<String> namedParameters = const <String>[]; |
425 List<ResolutionDartType> namedParameterTypes = const <ResolutionDartType>[]; | 438 List<ResolutionDartType> namedParameterTypes = const <ResolutionDartType>[]; |
426 List<Element> orderedOptionalParameters = | 439 List<Element> orderedOptionalParameters = |
427 visitor.optionalParameters.toList(); | 440 visitor.optionalParameters.toList(); |
428 if (visitor.optionalParametersAreNamed) { | 441 if (visitor.optionalParametersAreNamed) { |
429 // TODO(karlklose); replace when [visitor.optinalParameters] is a [List]. | 442 // TODO(karlklose); replace when [visitor.optionalParameters] is a [List]. |
430 orderedOptionalParameters.sort((Element a, Element b) { | 443 orderedOptionalParameters.sort((Element a, Element b) { |
431 return a.name.compareTo(b.name); | 444 return a.name.compareTo(b.name); |
432 }); | 445 }); |
433 LinkBuilder<String> namedParametersBuilder = new LinkBuilder<String>(); | 446 LinkBuilder<String> namedParametersBuilder = new LinkBuilder<String>(); |
434 LinkBuilder<ResolutionDartType> namedParameterTypesBuilder = | 447 LinkBuilder<ResolutionDartType> namedParameterTypesBuilder = |
435 new LinkBuilder<ResolutionDartType>(); | 448 new LinkBuilder<ResolutionDartType>(); |
436 for (FormalElement parameter in orderedOptionalParameters) { | 449 for (FormalElement parameter in orderedOptionalParameters) { |
437 namedParametersBuilder.addLast(parameter.name); | 450 namedParametersBuilder.addLast(parameter.name); |
438 namedParameterTypesBuilder.addLast(parameter.type); | 451 namedParameterTypesBuilder.addLast(parameter.type); |
439 } | 452 } |
440 namedParameters = namedParametersBuilder.toLink().toList(growable: false); | 453 namedParameters = namedParametersBuilder.toLink().toList(growable: false); |
441 namedParameterTypes = | 454 namedParameterTypes = |
442 namedParameterTypesBuilder.toLink().toList(growable: false); | 455 namedParameterTypesBuilder.toLink().toList(growable: false); |
443 } else { | 456 } else { |
444 // TODO(karlklose); replace when [visitor.optinalParameters] is a [List]. | 457 // TODO(karlklose); replace when [visitor.optionalParameters] is a [List]. |
445 LinkBuilder<ResolutionDartType> optionalParameterTypesBuilder = | 458 LinkBuilder<ResolutionDartType> optionalParameterTypesBuilder = |
446 new LinkBuilder<ResolutionDartType>(); | 459 new LinkBuilder<ResolutionDartType>(); |
447 for (FormalElement parameter in visitor.optionalParameters) { | 460 for (FormalElement parameter in visitor.optionalParameters) { |
448 optionalParameterTypesBuilder.addLast(parameter.type); | 461 optionalParameterTypesBuilder.addLast(parameter.type); |
449 } | 462 } |
450 optionalParameterTypes = | 463 optionalParameterTypes = |
451 optionalParameterTypesBuilder.toLink().toList(growable: false); | 464 optionalParameterTypesBuilder.toLink().toList(growable: false); |
452 } | 465 } |
453 ResolutionFunctionType type = new ResolutionFunctionType( | 466 ResolutionFunctionType type = new ResolutionFunctionType( |
454 element.declaration, | 467 element.declaration, |
455 returnType, | 468 returnType, |
456 parameterTypes.toLink().toList(growable: false), | 469 parameterTypes.toLink().toList(growable: false), |
457 optionalParameterTypes, | 470 optionalParameterTypes, |
458 namedParameters, | 471 namedParameters, |
459 namedParameterTypes); | 472 namedParameterTypes); |
460 return new FunctionSignatureX( | 473 return new FunctionSignatureX( |
461 typeVariables: typeVariableTypes, | 474 typeVariables: typeVariableTypes, |
462 requiredParameters: parameters, | 475 requiredParameters: parameters, |
463 optionalParameters: visitor.optionalParameters, | 476 optionalParameters: visitor.optionalParameters, |
464 requiredParameterCount: requiredParameterCount, | 477 requiredParameterCount: requiredParameterCount, |
465 optionalParameterCount: visitor.optionalParameterCount, | 478 optionalParameterCount: visitor.optionalParameterCount, |
466 optionalParametersAreNamed: visitor.optionalParametersAreNamed, | 479 optionalParametersAreNamed: visitor.optionalParametersAreNamed, |
467 orderedOptionalParameters: orderedOptionalParameters, | 480 orderedOptionalParameters: orderedOptionalParameters, |
468 type: type); | 481 type: type); |
469 } | 482 } |
470 | 483 |
471 ResolutionDartType resolveTypeAnnotation(TypeAnnotation annotation) { | 484 ResolutionDartType resolveTypeAnnotation(TypeAnnotation annotation) { |
472 ResolutionDartType type = resolveReturnType(annotation); | |
473 if (type.isVoid) { | |
474 reporter.reportErrorMessage(annotation, MessageKind.VOID_NOT_ALLOWED); | |
475 } | |
476 return type; | |
477 } | |
478 | |
479 ResolutionDartType resolveReturnType(TypeAnnotation annotation) { | |
480 if (annotation == null) return const ResolutionDynamicType(); | 485 if (annotation == null) return const ResolutionDynamicType(); |
481 ResolutionDartType result = resolver.resolveTypeAnnotation(annotation); | 486 ResolutionDartType result = resolver.resolveTypeAnnotation(annotation); |
482 if (result == null) { | 487 if (result == null) { |
483 return const ResolutionDynamicType(); | 488 return const ResolutionDynamicType(); |
484 } | 489 } |
485 return result; | 490 return result; |
486 } | 491 } |
487 } | 492 } |
488 | 493 |
489 /// Used during `SignatureResolver.analyze` to provide access to the type | 494 /// Used during `SignatureResolver.analyze` to provide access to the type |
490 /// variables of the function signature itself when its signature is analyzed. | 495 /// variables of the function signature itself when its signature is analyzed. |
491 class FunctionSignatureBuildingScope extends TypeVariablesScope { | 496 class FunctionSignatureBuildingScope extends TypeVariablesScope { |
492 @override | 497 @override |
493 final List<ResolutionDartType> typeVariables; | 498 final List<ResolutionDartType> typeVariables; |
494 | 499 |
495 FunctionSignatureBuildingScope(Scope parent, this.typeVariables) | 500 FunctionSignatureBuildingScope(Scope parent, this.typeVariables) |
496 : super(parent); | 501 : super(parent); |
497 | 502 |
498 String toString() => 'FunctionSignatureBuildingScope($typeVariables)'; | 503 String toString() => 'FunctionSignatureBuildingScope($typeVariables)'; |
499 } | 504 } |
OLD | NEW |