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 '../compiler.dart' show Compiler; | 8 import '../common/resolution.dart'; |
9 import '../dart_types.dart'; | 9 import '../dart_types.dart'; |
10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
11 import '../elements/modelx.dart' | 11 import '../elements/modelx.dart' |
12 show | 12 show |
13 ErroneousFieldElementX, | 13 ErroneousFieldElementX, |
14 ErroneousInitializingFormalElementX, | 14 ErroneousInitializingFormalElementX, |
15 FormalElementX, | 15 FormalElementX, |
16 FunctionSignatureX, | 16 FunctionSignatureX, |
17 InitializingFormalElementX, | 17 InitializingFormalElementX, |
18 LocalParameterElementX, | 18 LocalParameterElementX, |
(...skipping 14 matching lines...) Expand all Loading... |
33 final FunctionTypedElement enclosingElement; | 33 final FunctionTypedElement enclosingElement; |
34 final Scope scope; | 34 final Scope scope; |
35 final MessageKind defaultValuesError; | 35 final MessageKind defaultValuesError; |
36 final bool createRealParameters; | 36 final bool createRealParameters; |
37 List<Element> optionalParameters = const <Element>[]; | 37 List<Element> optionalParameters = const <Element>[]; |
38 int optionalParameterCount = 0; | 38 int optionalParameterCount = 0; |
39 bool isOptionalParameter = false; | 39 bool isOptionalParameter = false; |
40 bool optionalParametersAreNamed = false; | 40 bool optionalParametersAreNamed = false; |
41 VariableDefinitions currentDefinitions; | 41 VariableDefinitions currentDefinitions; |
42 | 42 |
43 SignatureResolver(Compiler compiler, FunctionTypedElement enclosingElement, | 43 SignatureResolver( |
44 Scope scope, ResolutionRegistry registry, | 44 Resolution resolution, |
45 {this.defaultValuesError, this.createRealParameters}) | 45 FunctionTypedElement enclosingElement, |
| 46 Scope scope, |
| 47 ResolutionRegistry registry, |
| 48 {this.defaultValuesError, |
| 49 this.createRealParameters}) |
46 : this.scope = scope, | 50 : this.scope = scope, |
47 this.enclosingElement = enclosingElement, | 51 this.enclosingElement = enclosingElement, |
48 this.resolver = new ResolverVisitor( | 52 this.resolver = new ResolverVisitor( |
49 compiler, enclosingElement, registry, | 53 resolution, enclosingElement, registry, |
50 scope: scope), | 54 scope: scope), |
51 super(compiler, registry); | 55 super(resolution, registry); |
52 | 56 |
53 bool get defaultValuesAllowed => defaultValuesError == null; | 57 bool get defaultValuesAllowed => defaultValuesError == null; |
54 | 58 |
55 visitNodeList(NodeList node) { | 59 visitNodeList(NodeList node) { |
56 // This must be a list of optional arguments. | 60 // This must be a list of optional arguments. |
57 String value = node.beginToken.stringValue; | 61 String value = node.beginToken.stringValue; |
58 if ((!identical(value, '[')) && (!identical(value, '{'))) { | 62 if ((!identical(value, '[')) && (!identical(value, '{'))) { |
59 reporter.internalError(node, "expected optional parameters"); | 63 reporter.internalError(node, "expected optional parameters"); |
60 } | 64 } |
61 optionalParametersAreNamed = (identical(value, '{')); | 65 optionalParametersAreNamed = (identical(value, '{')); |
(...skipping 24 matching lines...) Expand all Loading... |
86 reporter.reportErrorMessage(node, MessageKind.FORMAL_DECLARED_STATIC); | 90 reporter.reportErrorMessage(node, MessageKind.FORMAL_DECLARED_STATIC); |
87 } | 91 } |
88 | 92 |
89 if (currentDefinitions != null) { | 93 if (currentDefinitions != null) { |
90 reporter.internalError(node, 'function type parameters not supported'); | 94 reporter.internalError(node, 'function type parameters not supported'); |
91 } | 95 } |
92 currentDefinitions = node; | 96 currentDefinitions = node; |
93 FormalElementX element = definition.accept(this); | 97 FormalElementX element = definition.accept(this); |
94 if (currentDefinitions.metadata != null) { | 98 if (currentDefinitions.metadata != null) { |
95 element.metadataInternal = | 99 element.metadataInternal = |
96 compiler.resolver.resolveMetadata(element, node); | 100 resolution.resolver.resolveMetadata(element, node); |
97 } | 101 } |
98 currentDefinitions = null; | 102 currentDefinitions = null; |
99 return element; | 103 return element; |
100 } | 104 } |
101 | 105 |
102 void validateName(Identifier node) { | 106 void validateName(Identifier node) { |
103 if (isOptionalParameter && | 107 if (isOptionalParameter && |
104 optionalParametersAreNamed && | 108 optionalParametersAreNamed && |
105 Name.isPrivateName(node.source)) { | 109 Name.isPrivateName(node.source)) { |
106 reporter.reportErrorMessage(node, MessageKind.PRIVATE_NAMED_PARAMETER); | 110 reporter.reportErrorMessage(node, MessageKind.PRIVATE_NAMED_PARAMETER); |
107 } | 111 } |
108 } | 112 } |
109 | 113 |
110 void computeParameterType(FormalElementX element, | 114 void computeParameterType(FormalElementX element, |
111 [VariableElement fieldElement]) { | 115 [VariableElement fieldElement]) { |
112 void computeFunctionType(FunctionExpression functionExpression) { | 116 void computeFunctionType(FunctionExpression functionExpression) { |
113 FunctionSignature functionSignature = SignatureResolver.analyze( | 117 FunctionSignature functionSignature = SignatureResolver.analyze( |
114 compiler, | 118 resolution, |
115 scope, | 119 scope, |
116 functionExpression.typeVariables, | 120 functionExpression.typeVariables, |
117 functionExpression.parameters, | 121 functionExpression.parameters, |
118 functionExpression.returnType, | 122 functionExpression.returnType, |
119 element, | 123 element, |
120 registry, | 124 registry, |
121 defaultValuesError: MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT); | 125 defaultValuesError: MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT); |
122 element.functionSignature = functionSignature; | 126 element.functionSignature = functionSignature; |
123 } | 127 } |
124 | 128 |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 | 287 |
284 /** | 288 /** |
285 * Resolves formal parameters and return type of a [FunctionExpression] | 289 * Resolves formal parameters and return type of a [FunctionExpression] |
286 * to a [FunctionSignature]. | 290 * to a [FunctionSignature]. |
287 * | 291 * |
288 * If [createRealParameters] is `true`, the parameters will be | 292 * If [createRealParameters] is `true`, the parameters will be |
289 * real parameters implementing the [ParameterElement] interface. Otherwise, | 293 * real parameters implementing the [ParameterElement] interface. Otherwise, |
290 * the parameters will only implement [FormalElement]. | 294 * the parameters will only implement [FormalElement]. |
291 */ | 295 */ |
292 static FunctionSignature analyze( | 296 static FunctionSignature analyze( |
293 Compiler compiler, | 297 Resolution resolution, |
294 Scope scope, | 298 Scope scope, |
295 NodeList typeVariables, | 299 NodeList typeVariables, |
296 NodeList formalParameters, | 300 NodeList formalParameters, |
297 Node returnNode, | 301 Node returnNode, |
298 FunctionTypedElement element, | 302 FunctionTypedElement element, |
299 ResolutionRegistry registry, | 303 ResolutionRegistry registry, |
300 {MessageKind defaultValuesError, | 304 {MessageKind defaultValuesError, |
301 bool createRealParameters: false, | 305 bool createRealParameters: false, |
302 bool isFunctionExpression: false}) { | 306 bool isFunctionExpression: false}) { |
303 DiagnosticReporter reporter = compiler.reporter; | 307 DiagnosticReporter reporter = resolution.reporter; |
304 | 308 |
305 List<DartType> createTypeVariables(NodeList typeVariableNodes) { | 309 List<DartType> createTypeVariables(NodeList typeVariableNodes) { |
306 if (typeVariableNodes == null) return const <DartType>[]; | 310 if (typeVariableNodes == null) return const <DartType>[]; |
307 | 311 |
308 // Create the types and elements corresponding to [typeVariableNodes]. | 312 // Create the types and elements corresponding to [typeVariableNodes]. |
309 Link<Node> nodes = typeVariableNodes.nodes; | 313 Link<Node> nodes = typeVariableNodes.nodes; |
310 List<DartType> arguments = | 314 List<DartType> arguments = |
311 new List.generate(nodes.slowLength(), (int index) { | 315 new List.generate(nodes.slowLength(), (int index) { |
312 TypeVariable node = nodes.head; | 316 TypeVariable node = nodes.head; |
313 String variableName = node.name.source; | 317 String variableName = node.name.source; |
314 nodes = nodes.tail; | 318 nodes = nodes.tail; |
315 TypeVariableElementX variableElement = | 319 TypeVariableElementX variableElement = |
316 new TypeVariableElementX(variableName, element, index, node); | 320 new TypeVariableElementX(variableName, element, index, node); |
317 // GENERIC_METHODS: When method type variables are implemented fully we | 321 // GENERIC_METHODS: When method type variables are implemented fully we |
318 // must resolve the actual bounds; currently we just claim that | 322 // must resolve the actual bounds; currently we just claim that |
319 // every method type variable has upper bound [dynamic]. | 323 // every method type variable has upper bound [dynamic]. |
320 variableElement.boundCache = const DynamicType(); | 324 variableElement.boundCache = const DynamicType(); |
321 TypeVariableType variableType = | 325 TypeVariableType variableType = |
322 new MethodTypeVariableType(variableElement); | 326 new MethodTypeVariableType(variableElement); |
323 variableElement.typeCache = variableType; | 327 variableElement.typeCache = variableType; |
324 return variableType; | 328 return variableType; |
325 }, growable: false); | 329 }, growable: false); |
326 return arguments; | 330 return arguments; |
327 } | 331 } |
328 | 332 |
329 List<DartType> typeVariableTypes = createTypeVariables(typeVariables); | 333 List<DartType> typeVariableTypes = createTypeVariables(typeVariables); |
330 scope = new FunctionSignatureBuildingScope(scope, typeVariableTypes); | 334 scope = new FunctionSignatureBuildingScope(scope, typeVariableTypes); |
331 SignatureResolver visitor = new SignatureResolver( | 335 SignatureResolver visitor = new SignatureResolver( |
332 compiler, element, scope, registry, | 336 resolution, element, scope, registry, |
333 defaultValuesError: defaultValuesError, | 337 defaultValuesError: defaultValuesError, |
334 createRealParameters: createRealParameters); | 338 createRealParameters: createRealParameters); |
335 List<Element> parameters = const <Element>[]; | 339 List<Element> parameters = const <Element>[]; |
336 int requiredParameterCount = 0; | 340 int requiredParameterCount = 0; |
337 if (formalParameters == null) { | 341 if (formalParameters == null) { |
338 if (!element.isGetter) { | 342 if (!element.isGetter) { |
339 if (element.isMalformed) { | 343 if (element.isMalformed) { |
340 // If the element is erroneous, an error should already have been | 344 // If the element is erroneous, an error should already have been |
341 // reported. In the case of parse errors, it is possible that there | 345 // reported. In the case of parse errors, it is possible that there |
342 // are formal parameters, but something else in the method failed to | 346 // are formal parameters, but something else in the method failed to |
343 // parse. So we suppress the message about missing formals. | 347 // parse. So we suppress the message about missing formals. |
344 assert(invariant(element, compiler.compilationFailed)); | 348 assert(invariant(element, reporter.hasReportedError)); |
345 } else { | 349 } else { |
346 reporter.reportErrorMessage(element, MessageKind.MISSING_FORMALS); | 350 reporter.reportErrorMessage(element, MessageKind.MISSING_FORMALS); |
347 } | 351 } |
348 } | 352 } |
349 } else { | 353 } else { |
350 if (element.isGetter) { | 354 if (element.isGetter) { |
351 if (!identical( | 355 if (!identical( |
352 formalParameters.endToken.next.stringValue, | 356 formalParameters.endToken.next.stringValue, |
353 // TODO(ahe): Remove the check for native keyword. | 357 // TODO(ahe): Remove the check for native keyword. |
354 'native')) { | 358 'native')) { |
355 reporter.reportErrorMessage( | 359 reporter.reportErrorMessage( |
356 formalParameters, MessageKind.EXTRA_FORMALS); | 360 formalParameters, MessageKind.EXTRA_FORMALS); |
357 } | 361 } |
358 } | 362 } |
359 LinkBuilder<Element> parametersBuilder = | 363 LinkBuilder<Element> parametersBuilder = |
360 visitor.analyzeNodes(formalParameters.nodes); | 364 visitor.analyzeNodes(formalParameters.nodes); |
361 requiredParameterCount = parametersBuilder.length; | 365 requiredParameterCount = parametersBuilder.length; |
362 parameters = parametersBuilder.toList(); | 366 parameters = parametersBuilder.toList(); |
363 } | 367 } |
364 DartType returnType; | 368 DartType returnType; |
365 if (element.isFactoryConstructor) { | 369 if (element.isFactoryConstructor) { |
366 returnType = element.enclosingClass.thisType; | 370 returnType = element.enclosingClass.thisType; |
367 // Because there is no type annotation for the return type of | 371 // Because there is no type annotation for the return type of |
368 // this element, we explicitly add one. | 372 // this element, we explicitly add one. |
369 if (compiler.options.enableTypeAssertions) { | 373 if (resolution.options.enableTypeAssertions) { |
370 registry.registerTypeUse(new TypeUse.checkedModeCheck(returnType)); | 374 registry.registerTypeUse(new TypeUse.checkedModeCheck(returnType)); |
371 } | 375 } |
372 } else { | 376 } else { |
373 AsyncMarker asyncMarker = AsyncMarker.SYNC; | 377 AsyncMarker asyncMarker = AsyncMarker.SYNC; |
374 if (isFunctionExpression) { | 378 if (isFunctionExpression) { |
375 // Use async marker to determine the return type of function | 379 // Use async marker to determine the return type of function |
376 // expressions. | 380 // expressions. |
377 FunctionElement function = element; | 381 FunctionElement function = element; |
378 asyncMarker = function.asyncMarker; | 382 asyncMarker = function.asyncMarker; |
379 } | 383 } |
380 switch (asyncMarker) { | 384 switch (asyncMarker) { |
381 case AsyncMarker.SYNC: | 385 case AsyncMarker.SYNC: |
382 returnType = visitor.resolveReturnType(returnNode); | 386 returnType = visitor.resolveReturnType(returnNode); |
383 break; | 387 break; |
384 case AsyncMarker.SYNC_STAR: | 388 case AsyncMarker.SYNC_STAR: |
385 returnType = compiler.coreTypes.iterableType(); | 389 returnType = resolution.coreTypes.iterableType(); |
386 break; | 390 break; |
387 case AsyncMarker.ASYNC: | 391 case AsyncMarker.ASYNC: |
388 returnType = compiler.coreTypes.futureType(); | 392 returnType = resolution.coreTypes.futureType(); |
389 break; | 393 break; |
390 case AsyncMarker.ASYNC_STAR: | 394 case AsyncMarker.ASYNC_STAR: |
391 returnType = compiler.coreTypes.streamType(); | 395 returnType = resolution.coreTypes.streamType(); |
392 break; | 396 break; |
393 } | 397 } |
394 } | 398 } |
395 | 399 |
396 if (element.isSetter && | 400 if (element.isSetter && |
397 (requiredParameterCount != 1 || visitor.optionalParameterCount != 0)) { | 401 (requiredParameterCount != 1 || visitor.optionalParameterCount != 0)) { |
398 // If there are no formal parameters, we already reported an error above. | 402 // If there are no formal parameters, we already reported an error above. |
399 if (formalParameters != null) { | 403 if (formalParameters != null) { |
400 reporter.reportErrorMessage( | 404 reporter.reportErrorMessage( |
401 formalParameters, MessageKind.ILLEGAL_SETTER_FORMALS); | 405 formalParameters, MessageKind.ILLEGAL_SETTER_FORMALS); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 /// variables of the function signature itself when its signature is analyzed. | 479 /// variables of the function signature itself when its signature is analyzed. |
476 class FunctionSignatureBuildingScope extends TypeVariablesScope { | 480 class FunctionSignatureBuildingScope extends TypeVariablesScope { |
477 @override | 481 @override |
478 final List<DartType> typeVariables; | 482 final List<DartType> typeVariables; |
479 | 483 |
480 FunctionSignatureBuildingScope(Scope parent, this.typeVariables) | 484 FunctionSignatureBuildingScope(Scope parent, this.typeVariables) |
481 : super(parent); | 485 : super(parent); |
482 | 486 |
483 String toString() => 'FunctionSignatureBuildingScope($typeVariables)'; | 487 String toString() => 'FunctionSignatureBuildingScope($typeVariables)'; |
484 } | 488 } |
OLD | NEW |