| 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 17 matching lines...) Expand all Loading... |
| 28 | 28 |
| 29 /** | 29 /** |
| 30 * [SignatureResolver] resolves function signatures. | 30 * [SignatureResolver] resolves function signatures. |
| 31 */ | 31 */ |
| 32 class SignatureResolver extends MappingVisitor<FormalElementX> { | 32 class SignatureResolver extends MappingVisitor<FormalElementX> { |
| 33 final ResolverVisitor resolver; | 33 final ResolverVisitor resolver; |
| 34 final FunctionTypedElement enclosingElement; | 34 final FunctionTypedElement enclosingElement; |
| 35 final Scope scope; | 35 final Scope scope; |
| 36 final MessageKind defaultValuesError; | 36 final MessageKind defaultValuesError; |
| 37 final bool createRealParameters; | 37 final bool createRealParameters; |
| 38 List<Element> optionalParameters = const <Element>[]; | 38 List<FormalElement> optionalParameters = const <FormalElement>[]; |
| 39 int optionalParameterCount = 0; | 39 int optionalParameterCount = 0; |
| 40 bool isOptionalParameter = false; | 40 bool isOptionalParameter = false; |
| 41 bool optionalParametersAreNamed = false; | 41 bool optionalParametersAreNamed = false; |
| 42 VariableDefinitions currentDefinitions; | 42 VariableDefinitions currentDefinitions; |
| 43 | 43 |
| 44 SignatureResolver( | 44 SignatureResolver( |
| 45 Resolution resolution, | 45 Resolution resolution, |
| 46 FunctionTypedElement enclosingElement, | 46 FunctionTypedElement enclosingElement, |
| 47 Scope scope, | 47 Scope scope, |
| 48 ResolutionRegistry registry, | 48 ResolutionRegistry registry, |
| 49 {this.defaultValuesError, | 49 {this.defaultValuesError, |
| 50 this.createRealParameters}) | 50 this.createRealParameters}) |
| 51 : this.scope = scope, | 51 : this.scope = scope, |
| 52 this.enclosingElement = enclosingElement, | 52 this.enclosingElement = enclosingElement, |
| 53 this.resolver = new ResolverVisitor( | 53 this.resolver = new ResolverVisitor( |
| 54 resolution, enclosingElement, registry, | 54 resolution, enclosingElement, registry, |
| 55 scope: scope), | 55 scope: scope), |
| 56 super(resolution, registry); | 56 super(resolution, registry); |
| 57 | 57 |
| 58 bool get defaultValuesAllowed => defaultValuesError == null; | 58 bool get defaultValuesAllowed => defaultValuesError == null; |
| 59 | 59 |
| 60 visitNodeList(NodeList node) { | 60 visitNodeList(NodeList node) { |
| 61 // This must be a list of optional arguments. | 61 // This must be a list of optional arguments. |
| 62 String value = node.beginToken.stringValue; | 62 String value = node.beginToken.stringValue; |
| 63 if ((!identical(value, '[')) && (!identical(value, '{'))) { | 63 if ((!identical(value, '[')) && (!identical(value, '{'))) { |
| 64 reporter.internalError(node, "expected optional parameters"); | 64 reporter.internalError(node, "expected optional parameters"); |
| 65 } | 65 } |
| 66 optionalParametersAreNamed = (identical(value, '{')); | 66 optionalParametersAreNamed = (identical(value, '{')); |
| 67 isOptionalParameter = true; | 67 isOptionalParameter = true; |
| 68 LinkBuilder<Element> elements = analyzeNodes(node.nodes); | 68 LinkBuilder<FormalElement> elements = analyzeNodes(node.nodes); |
| 69 optionalParameterCount = elements.length; | 69 optionalParameterCount = elements.length; |
| 70 optionalParameters = elements.toList(); | 70 optionalParameters = elements.toList(); |
| 71 } | 71 } |
| 72 | 72 |
| 73 FormalElementX visitVariableDefinitions(VariableDefinitions node) { | 73 FormalElementX visitVariableDefinitions(VariableDefinitions node) { |
| 74 Link<Node> definitions = node.definitions.nodes; | 74 Link<Node> definitions = node.definitions.nodes; |
| 75 if (definitions.isEmpty) { | 75 if (definitions.isEmpty) { |
| 76 reporter.internalError(node, 'no parameter definition'); | 76 reporter.internalError(node, 'no parameter definition'); |
| 77 return null; | 77 return null; |
| 78 } | 78 } |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 } | 245 } |
| 246 element = new InitializingFormalElementX( | 246 element = new InitializingFormalElementX( |
| 247 enclosingElement, currentDefinitions, name, initializer, fieldElement, | 247 enclosingElement, currentDefinitions, name, initializer, fieldElement, |
| 248 isOptional: isOptionalParameter, isNamed: optionalParametersAreNamed); | 248 isOptional: isOptionalParameter, isNamed: optionalParametersAreNamed); |
| 249 computeParameterType(element, fieldElement); | 249 computeParameterType(element, fieldElement); |
| 250 } | 250 } |
| 251 return element; | 251 return element; |
| 252 } | 252 } |
| 253 | 253 |
| 254 /// A [SendSet] node is an optional parameter with a default value. | 254 /// A [SendSet] node is an optional parameter with a default value. |
| 255 Element visitSendSet(SendSet node) { | 255 FormalElementX visitSendSet(SendSet node) { |
| 256 FormalElementX element; | 256 FormalElementX element; |
| 257 if (node.receiver != null) { | 257 if (node.receiver != null) { |
| 258 element = createFieldParameter(node, node.arguments.first); | 258 element = createFieldParameter(node, node.arguments.first); |
| 259 } else if (node.selector.asIdentifier() != null || | 259 } else if (node.selector.asIdentifier() != null || |
| 260 node.selector.asFunctionExpression() != null) { | 260 node.selector.asFunctionExpression() != null) { |
| 261 element = createParameter(getParameterName(node), node.arguments.first); | 261 element = createParameter(getParameterName(node), node.arguments.first); |
| 262 } | 262 } |
| 263 Node defaultValue = node.arguments.head; | 263 Node defaultValue = node.arguments.head; |
| 264 if (!defaultValuesAllowed) { | 264 if (!defaultValuesAllowed) { |
| 265 reporter.reportErrorMessage(defaultValue, defaultValuesError); | 265 reporter.reportErrorMessage(defaultValue, defaultValuesError); |
| 266 } | 266 } |
| 267 return element; | 267 return element; |
| 268 } | 268 } |
| 269 | 269 |
| 270 Element visitFunctionExpression(FunctionExpression node) { | 270 FormalElementX visitFunctionExpression(FunctionExpression node) { |
| 271 // This is a function typed parameter. | 271 // This is a function typed parameter. |
| 272 Modifiers modifiers = currentDefinitions.modifiers; | 272 Modifiers modifiers = currentDefinitions.modifiers; |
| 273 if (modifiers.isFinal) { | 273 if (modifiers.isFinal) { |
| 274 reporter.reportErrorMessage( | 274 reporter.reportErrorMessage( |
| 275 modifiers, MessageKind.FINAL_FUNCTION_TYPE_PARAMETER); | 275 modifiers, MessageKind.FINAL_FUNCTION_TYPE_PARAMETER); |
| 276 } | 276 } |
| 277 if (modifiers.isVar) { | 277 if (modifiers.isVar) { |
| 278 reporter.reportErrorMessage( | 278 reporter.reportErrorMessage( |
| 279 modifiers, MessageKind.VAR_FUNCTION_TYPE_PARAMETER); | 279 modifiers, MessageKind.VAR_FUNCTION_TYPE_PARAMETER); |
| 280 } | 280 } |
| 281 | 281 |
| 282 return createParameter(node.name, null); | 282 return createParameter(node.name, null); |
| 283 } | 283 } |
| 284 | 284 |
| 285 LinkBuilder<Element> analyzeNodes(Link<Node> link) { | 285 LinkBuilder<FormalElement> analyzeNodes(Link<Node> link) { |
| 286 LinkBuilder<Element> elements = new LinkBuilder<Element>(); | 286 LinkBuilder<FormalElement> elements = new LinkBuilder<FormalElement>(); |
| 287 for (; !link.isEmpty; link = link.tail) { | 287 for (; !link.isEmpty; link = link.tail) { |
| 288 Element element = link.head.accept(this); | 288 Element element = link.head.accept(this); |
| 289 if (element != null) { | 289 if (element != null) { |
| 290 elements.addLast(element); | 290 elements.addLast(element); |
| 291 } else { | 291 } else { |
| 292 // If parameter is null, the current node should be the last, | 292 // If parameter is null, the current node should be the last, |
| 293 // and a list of optional named parameters. | 293 // and a list of optional named parameters. |
| 294 if (!link.tail.isEmpty || (link.head is! NodeList)) { | 294 if (!link.tail.isEmpty || (link.head is! NodeList)) { |
| 295 reporter.internalError(link.head, "expected optional parameters"); | 295 reporter.internalError(link.head, "expected optional parameters"); |
| 296 } | 296 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 return arguments; | 349 return arguments; |
| 350 } | 350 } |
| 351 | 351 |
| 352 List<ResolutionDartType> typeVariableTypes = | 352 List<ResolutionDartType> typeVariableTypes = |
| 353 createTypeVariables(typeVariables); | 353 createTypeVariables(typeVariables); |
| 354 scope = new FunctionSignatureBuildingScope(scope, typeVariableTypes); | 354 scope = new FunctionSignatureBuildingScope(scope, typeVariableTypes); |
| 355 SignatureResolver visitor = new SignatureResolver( | 355 SignatureResolver visitor = new SignatureResolver( |
| 356 resolution, element, scope, registry, | 356 resolution, element, scope, registry, |
| 357 defaultValuesError: defaultValuesError, | 357 defaultValuesError: defaultValuesError, |
| 358 createRealParameters: createRealParameters); | 358 createRealParameters: createRealParameters); |
| 359 List<Element> parameters = const <Element>[]; | 359 List<FormalElement> parameters = const <FormalElement>[]; |
| 360 int requiredParameterCount = 0; | 360 int requiredParameterCount = 0; |
| 361 if (formalParameters == null) { | 361 if (formalParameters == null) { |
| 362 if (!element.isGetter) { | 362 if (!element.isGetter) { |
| 363 if (element.isMalformed) { | 363 if (element.isMalformed) { |
| 364 // If the element is erroneous, an error should already have been | 364 // If the element is erroneous, an error should already have been |
| 365 // reported. In the case of parse errors, it is possible that there | 365 // reported. In the case of parse errors, it is possible that there |
| 366 // are formal parameters, but something else in the method failed to | 366 // are formal parameters, but something else in the method failed to |
| 367 // parse. So we suppress the message about missing formals. | 367 // parse. So we suppress the message about missing formals. |
| 368 assert(reporter.hasReportedError, failedAt(element)); | 368 assert(reporter.hasReportedError, failedAt(element)); |
| 369 } else { | 369 } else { |
| 370 reporter.reportErrorMessage(element, MessageKind.MISSING_FORMALS); | 370 reporter.reportErrorMessage(element, MessageKind.MISSING_FORMALS); |
| 371 } | 371 } |
| 372 } | 372 } |
| 373 } else { | 373 } else { |
| 374 if (element.isGetter) { | 374 if (element.isGetter) { |
| 375 if (!identical( | 375 if (!identical( |
| 376 formalParameters.endToken.next.stringValue, | 376 formalParameters.endToken.next.stringValue, |
| 377 // TODO(ahe): Remove the check for native keyword. | 377 // TODO(ahe): Remove the check for native keyword. |
| 378 'native')) { | 378 'native')) { |
| 379 reporter.reportErrorMessage( | 379 reporter.reportErrorMessage( |
| 380 formalParameters, MessageKind.EXTRA_FORMALS); | 380 formalParameters, MessageKind.EXTRA_FORMALS); |
| 381 } | 381 } |
| 382 } | 382 } |
| 383 LinkBuilder<Element> parametersBuilder = | 383 LinkBuilder<FormalElement> parametersBuilder = |
| 384 visitor.analyzeNodes(formalParameters.nodes); | 384 visitor.analyzeNodes(formalParameters.nodes); |
| 385 requiredParameterCount = parametersBuilder.length; | 385 requiredParameterCount = parametersBuilder.length; |
| 386 parameters = parametersBuilder.toList(); | 386 parameters = parametersBuilder.toList(); |
| 387 } | 387 } |
| 388 ResolutionDartType returnType; | 388 ResolutionDartType returnType; |
| 389 if (element.isFactoryConstructor) { | 389 if (element.isFactoryConstructor) { |
| 390 returnType = element.enclosingClass.thisType; | 390 returnType = element.enclosingClass.thisType; |
| 391 // Because there is no type annotation for the return type of | 391 // Because there is no type annotation for the return type of |
| 392 // this element, we explicitly add one. | 392 // this element, we explicitly add one. |
| 393 registry.registerCheckedModeCheck(returnType); | 393 registry.registerCheckedModeCheck(returnType); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 } | 431 } |
| 432 LinkBuilder<ResolutionDartType> parameterTypes = | 432 LinkBuilder<ResolutionDartType> parameterTypes = |
| 433 new LinkBuilder<ResolutionDartType>(); | 433 new LinkBuilder<ResolutionDartType>(); |
| 434 for (FormalElement parameter in parameters) { | 434 for (FormalElement parameter in parameters) { |
| 435 parameterTypes.addLast(parameter.type); | 435 parameterTypes.addLast(parameter.type); |
| 436 } | 436 } |
| 437 List<ResolutionDartType> optionalParameterTypes = | 437 List<ResolutionDartType> optionalParameterTypes = |
| 438 const <ResolutionDartType>[]; | 438 const <ResolutionDartType>[]; |
| 439 List<String> namedParameters = const <String>[]; | 439 List<String> namedParameters = const <String>[]; |
| 440 List<ResolutionDartType> namedParameterTypes = const <ResolutionDartType>[]; | 440 List<ResolutionDartType> namedParameterTypes = const <ResolutionDartType>[]; |
| 441 List<Element> orderedOptionalParameters = | 441 List<FormalElement> orderedOptionalParameters = |
| 442 visitor.optionalParameters.toList(); | 442 visitor.optionalParameters.toList(); |
| 443 if (visitor.optionalParametersAreNamed) { | 443 if (visitor.optionalParametersAreNamed) { |
| 444 // TODO(karlklose); replace when [visitor.optionalParameters] is a [List]. | 444 // TODO(karlklose); replace when [visitor.optionalParameters] is a [List]. |
| 445 orderedOptionalParameters.sort((Element a, Element b) { | 445 orderedOptionalParameters.sort((Element a, Element b) { |
| 446 return a.name.compareTo(b.name); | 446 return a.name.compareTo(b.name); |
| 447 }); | 447 }); |
| 448 LinkBuilder<String> namedParametersBuilder = new LinkBuilder<String>(); | 448 LinkBuilder<String> namedParametersBuilder = new LinkBuilder<String>(); |
| 449 LinkBuilder<ResolutionDartType> namedParameterTypesBuilder = | 449 LinkBuilder<ResolutionDartType> namedParameterTypesBuilder = |
| 450 new LinkBuilder<ResolutionDartType>(); | 450 new LinkBuilder<ResolutionDartType>(); |
| 451 for (FormalElement parameter in orderedOptionalParameters) { | 451 for (FormalElement parameter in orderedOptionalParameters) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 /// variables of the function signature itself when its signature is analyzed. | 505 /// variables of the function signature itself when its signature is analyzed. |
| 506 class FunctionSignatureBuildingScope extends TypeVariablesScope { | 506 class FunctionSignatureBuildingScope extends TypeVariablesScope { |
| 507 @override | 507 @override |
| 508 final List<ResolutionDartType> typeVariables; | 508 final List<ResolutionDartType> typeVariables; |
| 509 | 509 |
| 510 FunctionSignatureBuildingScope(Scope parent, this.typeVariables) | 510 FunctionSignatureBuildingScope(Scope parent, this.typeVariables) |
| 511 : super(parent); | 511 : super(parent); |
| 512 | 512 |
| 513 String toString() => 'FunctionSignatureBuildingScope($typeVariables)'; | 513 String toString() => 'FunctionSignatureBuildingScope($typeVariables)'; |
| 514 } | 514 } |
| OLD | NEW |