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 |