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 |