| 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 '../compiler.dart' show | 7 import '../compiler.dart' show |
| 8 Compiler; | 8 Compiler; |
| 9 import '../dart_types.dart'; | 9 import '../dart_types.dart'; |
| 10 import '../diagnostics/invariant.dart' show | 10 import '../diagnostics/invariant.dart' show |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 this.resolver = | 59 this.resolver = |
| 60 new ResolverVisitor(compiler, enclosingElement, registry), | 60 new ResolverVisitor(compiler, enclosingElement, registry), |
| 61 super(compiler, registry); | 61 super(compiler, registry); |
| 62 | 62 |
| 63 bool get defaultValuesAllowed => defaultValuesError == null; | 63 bool get defaultValuesAllowed => defaultValuesError == null; |
| 64 | 64 |
| 65 visitNodeList(NodeList node) { | 65 visitNodeList(NodeList node) { |
| 66 // This must be a list of optional arguments. | 66 // This must be a list of optional arguments. |
| 67 String value = node.beginToken.stringValue; | 67 String value = node.beginToken.stringValue; |
| 68 if ((!identical(value, '[')) && (!identical(value, '{'))) { | 68 if ((!identical(value, '[')) && (!identical(value, '{'))) { |
| 69 internalError(node, "expected optional parameters"); | 69 compiler.internalError(node, "expected optional parameters"); |
| 70 } | 70 } |
| 71 optionalParametersAreNamed = (identical(value, '{')); | 71 optionalParametersAreNamed = (identical(value, '{')); |
| 72 isOptionalParameter = true; | 72 isOptionalParameter = true; |
| 73 LinkBuilder<Element> elements = analyzeNodes(node.nodes); | 73 LinkBuilder<Element> elements = analyzeNodes(node.nodes); |
| 74 optionalParameterCount = elements.length; | 74 optionalParameterCount = elements.length; |
| 75 optionalParameters = elements.toList(); | 75 optionalParameters = elements.toList(); |
| 76 } | 76 } |
| 77 | 77 |
| 78 FormalElementX visitVariableDefinitions(VariableDefinitions node) { | 78 FormalElementX visitVariableDefinitions(VariableDefinitions node) { |
| 79 Link<Node> definitions = node.definitions.nodes; | 79 Link<Node> definitions = node.definitions.nodes; |
| 80 if (definitions.isEmpty) { | 80 if (definitions.isEmpty) { |
| 81 internalError(node, 'no parameter definition'); | 81 compiler.internalError(node, 'no parameter definition'); |
| 82 return null; | 82 return null; |
| 83 } | 83 } |
| 84 if (!definitions.tail.isEmpty) { | 84 if (!definitions.tail.isEmpty) { |
| 85 internalError(definitions.tail.head, 'extra definition'); | 85 compiler.internalError(definitions.tail.head, 'extra definition'); |
| 86 return null; | 86 return null; |
| 87 } | 87 } |
| 88 Node definition = definitions.head; | 88 Node definition = definitions.head; |
| 89 if (definition is NodeList) { | 89 if (definition is NodeList) { |
| 90 internalError(node, 'optional parameters are not implemented'); | 90 compiler.internalError(node, 'optional parameters are not implemented'); |
| 91 } | 91 } |
| 92 if (node.modifiers.isConst) { | 92 if (node.modifiers.isConst) { |
| 93 compiler.reportError(node, MessageKind.FORMAL_DECLARED_CONST); | 93 compiler.reportErrorMessage(node, MessageKind.FORMAL_DECLARED_CONST); |
| 94 } | 94 } |
| 95 if (node.modifiers.isStatic) { | 95 if (node.modifiers.isStatic) { |
| 96 compiler.reportError(node, MessageKind.FORMAL_DECLARED_STATIC); | 96 compiler.reportErrorMessage(node, MessageKind.FORMAL_DECLARED_STATIC); |
| 97 } | 97 } |
| 98 | 98 |
| 99 if (currentDefinitions != null) { | 99 if (currentDefinitions != null) { |
| 100 internalError(node, 'function type parameters not supported'); | 100 compiler.internalError(node, 'function type parameters not supported'); |
| 101 } | 101 } |
| 102 currentDefinitions = node; | 102 currentDefinitions = node; |
| 103 FormalElementX element = definition.accept(this); | 103 FormalElementX element = definition.accept(this); |
| 104 if (currentDefinitions.metadata != null) { | 104 if (currentDefinitions.metadata != null) { |
| 105 element.metadataInternal = | 105 element.metadataInternal = |
| 106 compiler.resolver.resolveMetadata(element, node); | 106 compiler.resolver.resolveMetadata(element, node); |
| 107 } | 107 } |
| 108 currentDefinitions = null; | 108 currentDefinitions = null; |
| 109 return element; | 109 return element; |
| 110 } | 110 } |
| 111 | 111 |
| 112 void validateName(Identifier node) { | 112 void validateName(Identifier node) { |
| 113 if (isOptionalParameter && | 113 if (isOptionalParameter && |
| 114 optionalParametersAreNamed && | 114 optionalParametersAreNamed && |
| 115 Name.isPrivateName(node.source)) { | 115 Name.isPrivateName(node.source)) { |
| 116 compiler.reportError(node, MessageKind.PRIVATE_NAMED_PARAMETER); | 116 compiler.reportErrorMessage(node, MessageKind.PRIVATE_NAMED_PARAMETER); |
| 117 } | 117 } |
| 118 } | 118 } |
| 119 | 119 |
| 120 void computeParameterType(FormalElementX element, | 120 void computeParameterType(FormalElementX element, |
| 121 [VariableElement fieldElement]) { | 121 [VariableElement fieldElement]) { |
| 122 void computeFunctionType(FunctionExpression functionExpression) { | 122 void computeFunctionType(FunctionExpression functionExpression) { |
| 123 FunctionSignature functionSignature = SignatureResolver.analyze( | 123 FunctionSignature functionSignature = SignatureResolver.analyze( |
| 124 compiler, functionExpression.parameters, | 124 compiler, functionExpression.parameters, |
| 125 functionExpression.returnType, element, registry, | 125 functionExpression.returnType, element, registry, |
| 126 defaultValuesError: MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT); | 126 defaultValuesError: MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 if (identifier != null) { | 165 if (identifier != null) { |
| 166 // Normal parameter: [:Type name:]. | 166 // Normal parameter: [:Type name:]. |
| 167 return identifier; | 167 return identifier; |
| 168 } else { | 168 } else { |
| 169 // Function type parameter: [:void name(DartType arg):]. | 169 // Function type parameter: [:void name(DartType arg):]. |
| 170 var functionExpression = node.selector.asFunctionExpression(); | 170 var functionExpression = node.selector.asFunctionExpression(); |
| 171 if (functionExpression != null && | 171 if (functionExpression != null && |
| 172 functionExpression.name.asIdentifier() != null) { | 172 functionExpression.name.asIdentifier() != null) { |
| 173 return functionExpression.name.asIdentifier(); | 173 return functionExpression.name.asIdentifier(); |
| 174 } else { | 174 } else { |
| 175 internalError(node, | 175 compiler.internalError(node, |
| 176 'internal error: unimplemented receiver on parameter send'); | 176 'internal error: unimplemented receiver on parameter send'); |
| 177 return null; | 177 return null; |
| 178 } | 178 } |
| 179 } | 179 } |
| 180 } | 180 } |
| 181 | 181 |
| 182 // The only valid [Send] can be in constructors and must be of the form | 182 // The only valid [Send] can be in constructors and must be of the form |
| 183 // [:this.x:] (where [:x:] represents an instance field). | 183 // [:this.x:] (where [:x:] represents an instance field). |
| 184 InitializingFormalElementX visitSend(Send node) { | 184 InitializingFormalElementX visitSend(Send node) { |
| 185 return createFieldParameter(node, null); | 185 return createFieldParameter(node, null); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 198 } | 198 } |
| 199 computeParameterType(parameter); | 199 computeParameterType(parameter); |
| 200 return parameter; | 200 return parameter; |
| 201 } | 201 } |
| 202 | 202 |
| 203 InitializingFormalElementX createFieldParameter(Send node, | 203 InitializingFormalElementX createFieldParameter(Send node, |
| 204 Expression initializer) { | 204 Expression initializer) { |
| 205 InitializingFormalElementX element; | 205 InitializingFormalElementX element; |
| 206 Identifier receiver = node.receiver.asIdentifier(); | 206 Identifier receiver = node.receiver.asIdentifier(); |
| 207 if (receiver == null || !receiver.isThis()) { | 207 if (receiver == null || !receiver.isThis()) { |
| 208 error(node, MessageKind.INVALID_PARAMETER); | 208 compiler.reportErrorMessage(node, MessageKind.INVALID_PARAMETER); |
| 209 return new ErroneousInitializingFormalElementX( | 209 return new ErroneousInitializingFormalElementX( |
| 210 getParameterName(node), enclosingElement); | 210 getParameterName(node), enclosingElement); |
| 211 } else { | 211 } else { |
| 212 if (!enclosingElement.isGenerativeConstructor) { | 212 if (!enclosingElement.isGenerativeConstructor) { |
| 213 error(node, MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED); | 213 compiler.reportErrorMessage( |
| 214 node, MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED); |
| 214 return new ErroneousInitializingFormalElementX( | 215 return new ErroneousInitializingFormalElementX( |
| 215 getParameterName(node), enclosingElement); | 216 getParameterName(node), enclosingElement); |
| 216 } | 217 } |
| 217 Identifier name = getParameterName(node); | 218 Identifier name = getParameterName(node); |
| 218 validateName(name); | 219 validateName(name); |
| 219 Element fieldElement = | 220 Element fieldElement = |
| 220 enclosingElement.enclosingClass.lookupLocalMember(name.source); | 221 enclosingElement.enclosingClass.lookupLocalMember(name.source); |
| 221 if (fieldElement == null || | 222 if (fieldElement == null || |
| 222 !identical(fieldElement.kind, ElementKind.FIELD)) { | 223 !identical(fieldElement.kind, ElementKind.FIELD)) { |
| 223 error(node, MessageKind.NOT_A_FIELD, {'fieldName': name}); | 224 compiler.reportErrorMessage( |
| 225 node, MessageKind.NOT_A_FIELD, {'fieldName': name}); |
| 224 fieldElement = new ErroneousFieldElementX( | 226 fieldElement = new ErroneousFieldElementX( |
| 225 name, enclosingElement.enclosingClass); | 227 name, enclosingElement.enclosingClass); |
| 226 } else if (!fieldElement.isInstanceMember) { | 228 } else if (!fieldElement.isInstanceMember) { |
| 227 error(node, MessageKind.NOT_INSTANCE_FIELD, {'fieldName': name}); | 229 compiler.reportErrorMessage( |
| 230 node, MessageKind.NOT_INSTANCE_FIELD, {'fieldName': name}); |
| 228 fieldElement = new ErroneousFieldElementX( | 231 fieldElement = new ErroneousFieldElementX( |
| 229 name, enclosingElement.enclosingClass); | 232 name, enclosingElement.enclosingClass); |
| 230 } | 233 } |
| 231 element = new InitializingFormalElementX(enclosingElement, | 234 element = new InitializingFormalElementX(enclosingElement, |
| 232 currentDefinitions, name, initializer, fieldElement, | 235 currentDefinitions, name, initializer, fieldElement, |
| 233 isOptional: isOptionalParameter, isNamed: optionalParametersAreNamed); | 236 isOptional: isOptionalParameter, isNamed: optionalParametersAreNamed); |
| 234 computeParameterType(element, fieldElement); | 237 computeParameterType(element, fieldElement); |
| 235 } | 238 } |
| 236 return element; | 239 return element; |
| 237 } | 240 } |
| 238 | 241 |
| 239 /// A [SendSet] node is an optional parameter with a default value. | 242 /// A [SendSet] node is an optional parameter with a default value. |
| 240 Element visitSendSet(SendSet node) { | 243 Element visitSendSet(SendSet node) { |
| 241 FormalElementX element; | 244 FormalElementX element; |
| 242 if (node.receiver != null) { | 245 if (node.receiver != null) { |
| 243 element = createFieldParameter(node, node.arguments.first); | 246 element = createFieldParameter(node, node.arguments.first); |
| 244 } else if (node.selector.asIdentifier() != null || | 247 } else if (node.selector.asIdentifier() != null || |
| 245 node.selector.asFunctionExpression() != null) { | 248 node.selector.asFunctionExpression() != null) { |
| 246 element = createParameter(getParameterName(node), node.arguments.first); | 249 element = createParameter(getParameterName(node), node.arguments.first); |
| 247 } | 250 } |
| 248 Node defaultValue = node.arguments.head; | 251 Node defaultValue = node.arguments.head; |
| 249 if (!defaultValuesAllowed) { | 252 if (!defaultValuesAllowed) { |
| 250 compiler.reportError(defaultValue, defaultValuesError); | 253 compiler.reportErrorMessage(defaultValue, defaultValuesError); |
| 251 } | 254 } |
| 252 return element; | 255 return element; |
| 253 } | 256 } |
| 254 | 257 |
| 255 Element visitFunctionExpression(FunctionExpression node) { | 258 Element visitFunctionExpression(FunctionExpression node) { |
| 256 // This is a function typed parameter. | 259 // This is a function typed parameter. |
| 257 Modifiers modifiers = currentDefinitions.modifiers; | 260 Modifiers modifiers = currentDefinitions.modifiers; |
| 258 if (modifiers.isFinal) { | 261 if (modifiers.isFinal) { |
| 259 compiler.reportError(modifiers, | 262 compiler.reportErrorMessage( |
| 263 modifiers, |
| 260 MessageKind.FINAL_FUNCTION_TYPE_PARAMETER); | 264 MessageKind.FINAL_FUNCTION_TYPE_PARAMETER); |
| 261 } | 265 } |
| 262 if (modifiers.isVar) { | 266 if (modifiers.isVar) { |
| 263 compiler.reportError(modifiers, MessageKind.VAR_FUNCTION_TYPE_PARAMETER); | 267 compiler.reportErrorMessage( |
| 268 modifiers, MessageKind.VAR_FUNCTION_TYPE_PARAMETER); |
| 264 } | 269 } |
| 265 | 270 |
| 266 return createParameter(node.name, null); | 271 return createParameter(node.name, null); |
| 267 } | 272 } |
| 268 | 273 |
| 269 LinkBuilder<Element> analyzeNodes(Link<Node> link) { | 274 LinkBuilder<Element> analyzeNodes(Link<Node> link) { |
| 270 LinkBuilder<Element> elements = new LinkBuilder<Element>(); | 275 LinkBuilder<Element> elements = new LinkBuilder<Element>(); |
| 271 for (; !link.isEmpty; link = link.tail) { | 276 for (; !link.isEmpty; link = link.tail) { |
| 272 Element element = link.head.accept(this); | 277 Element element = link.head.accept(this); |
| 273 if (element != null) { | 278 if (element != null) { |
| 274 elements.addLast(element); | 279 elements.addLast(element); |
| 275 } else { | 280 } else { |
| 276 // If parameter is null, the current node should be the last, | 281 // If parameter is null, the current node should be the last, |
| 277 // and a list of optional named parameters. | 282 // and a list of optional named parameters. |
| 278 if (!link.tail.isEmpty || (link.head is !NodeList)) { | 283 if (!link.tail.isEmpty || (link.head is !NodeList)) { |
| 279 internalError(link.head, "expected optional parameters"); | 284 compiler.internalError(link.head, "expected optional parameters"); |
| 280 } | 285 } |
| 281 } | 286 } |
| 282 } | 287 } |
| 283 return elements; | 288 return elements; |
| 284 } | 289 } |
| 285 | 290 |
| 286 /** | 291 /** |
| 287 * Resolves formal parameters and return type of a [FunctionExpression] | 292 * Resolves formal parameters and return type of a [FunctionExpression] |
| 288 * to a [FunctionSignature]. | 293 * to a [FunctionSignature]. |
| 289 * | 294 * |
| (...skipping 18 matching lines...) Expand all Loading... |
| 308 int requiredParameterCount = 0; | 313 int requiredParameterCount = 0; |
| 309 if (formalParameters == null) { | 314 if (formalParameters == null) { |
| 310 if (!element.isGetter) { | 315 if (!element.isGetter) { |
| 311 if (element.isErroneous) { | 316 if (element.isErroneous) { |
| 312 // If the element is erroneous, an error should already have been | 317 // If the element is erroneous, an error should already have been |
| 313 // reported. In the case of parse errors, it is possible that there | 318 // reported. In the case of parse errors, it is possible that there |
| 314 // are formal parameters, but something else in the method failed to | 319 // are formal parameters, but something else in the method failed to |
| 315 // parse. So we suppress the message about missing formals. | 320 // parse. So we suppress the message about missing formals. |
| 316 assert(invariant(element, compiler.compilationFailed)); | 321 assert(invariant(element, compiler.compilationFailed)); |
| 317 } else { | 322 } else { |
| 318 compiler.reportError(element, MessageKind.MISSING_FORMALS); | 323 compiler.reportErrorMessage(element, MessageKind.MISSING_FORMALS); |
| 319 } | 324 } |
| 320 } | 325 } |
| 321 } else { | 326 } else { |
| 322 if (element.isGetter) { | 327 if (element.isGetter) { |
| 323 if (!identical(formalParameters.endToken.next.stringValue, | 328 if (!identical(formalParameters.endToken.next.stringValue, |
| 324 // TODO(ahe): Remove the check for native keyword. | 329 // TODO(ahe): Remove the check for native keyword. |
| 325 'native')) { | 330 'native')) { |
| 326 compiler.reportError(formalParameters, | 331 compiler.reportErrorMessage( |
| 327 MessageKind.EXTRA_FORMALS); | 332 formalParameters, |
| 333 MessageKind.EXTRA_FORMALS); |
| 328 } | 334 } |
| 329 } | 335 } |
| 330 LinkBuilder<Element> parametersBuilder = | 336 LinkBuilder<Element> parametersBuilder = |
| 331 visitor.analyzeNodes(formalParameters.nodes); | 337 visitor.analyzeNodes(formalParameters.nodes); |
| 332 requiredParameterCount = parametersBuilder.length; | 338 requiredParameterCount = parametersBuilder.length; |
| 333 parameters = parametersBuilder.toList(); | 339 parameters = parametersBuilder.toList(); |
| 334 } | 340 } |
| 335 DartType returnType; | 341 DartType returnType; |
| 336 if (element.isFactoryConstructor) { | 342 if (element.isFactoryConstructor) { |
| 337 returnType = element.enclosingClass.thisType; | 343 returnType = element.enclosingClass.thisType; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 361 case AsyncMarker.ASYNC_STAR: | 367 case AsyncMarker.ASYNC_STAR: |
| 362 returnType = compiler.coreTypes.streamType(); | 368 returnType = compiler.coreTypes.streamType(); |
| 363 break; | 369 break; |
| 364 } | 370 } |
| 365 } | 371 } |
| 366 | 372 |
| 367 if (element.isSetter && (requiredParameterCount != 1 || | 373 if (element.isSetter && (requiredParameterCount != 1 || |
| 368 visitor.optionalParameterCount != 0)) { | 374 visitor.optionalParameterCount != 0)) { |
| 369 // If there are no formal parameters, we already reported an error above. | 375 // If there are no formal parameters, we already reported an error above. |
| 370 if (formalParameters != null) { | 376 if (formalParameters != null) { |
| 371 compiler.reportError(formalParameters, | 377 compiler.reportErrorMessage( |
| 372 MessageKind.ILLEGAL_SETTER_FORMALS); | 378 formalParameters, |
| 379 MessageKind.ILLEGAL_SETTER_FORMALS); |
| 373 } | 380 } |
| 374 } | 381 } |
| 375 LinkBuilder<DartType> parameterTypes = new LinkBuilder<DartType>(); | 382 LinkBuilder<DartType> parameterTypes = new LinkBuilder<DartType>(); |
| 376 for (FormalElement parameter in parameters) { | 383 for (FormalElement parameter in parameters) { |
| 377 parameterTypes.addLast(parameter.type); | 384 parameterTypes.addLast(parameter.type); |
| 378 } | 385 } |
| 379 List<DartType> optionalParameterTypes = const <DartType>[]; | 386 List<DartType> optionalParameterTypes = const <DartType>[]; |
| 380 List<String> namedParameters = const <String>[]; | 387 List<String> namedParameters = const <String>[]; |
| 381 List<DartType> namedParameterTypes = const <DartType>[]; | 388 List<DartType> namedParameterTypes = const <DartType>[]; |
| 382 List<Element> orderedOptionalParameters = | 389 List<Element> orderedOptionalParameters = |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 requiredParameterCount: requiredParameterCount, | 426 requiredParameterCount: requiredParameterCount, |
| 420 optionalParameterCount: visitor.optionalParameterCount, | 427 optionalParameterCount: visitor.optionalParameterCount, |
| 421 optionalParametersAreNamed: visitor.optionalParametersAreNamed, | 428 optionalParametersAreNamed: visitor.optionalParametersAreNamed, |
| 422 orderedOptionalParameters: orderedOptionalParameters, | 429 orderedOptionalParameters: orderedOptionalParameters, |
| 423 type: type); | 430 type: type); |
| 424 } | 431 } |
| 425 | 432 |
| 426 DartType resolveTypeAnnotation(TypeAnnotation annotation) { | 433 DartType resolveTypeAnnotation(TypeAnnotation annotation) { |
| 427 DartType type = resolveReturnType(annotation); | 434 DartType type = resolveReturnType(annotation); |
| 428 if (type.isVoid) { | 435 if (type.isVoid) { |
| 429 compiler.reportError(annotation, MessageKind.VOID_NOT_ALLOWED); | 436 compiler.reportErrorMessage(annotation, MessageKind.VOID_NOT_ALLOWED); |
| 430 } | 437 } |
| 431 return type; | 438 return type; |
| 432 } | 439 } |
| 433 | 440 |
| 434 DartType resolveReturnType(TypeAnnotation annotation) { | 441 DartType resolveReturnType(TypeAnnotation annotation) { |
| 435 if (annotation == null) return const DynamicType(); | 442 if (annotation == null) return const DynamicType(); |
| 436 DartType result = resolver.resolveTypeAnnotation(annotation); | 443 DartType result = resolver.resolveTypeAnnotation(annotation); |
| 437 if (result == null) { | 444 if (result == null) { |
| 438 return const DynamicType(); | 445 return const DynamicType(); |
| 439 } | 446 } |
| 440 return result; | 447 return result; |
| 441 } | 448 } |
| 442 } | 449 } |
| OLD | NEW |