OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 fasta.body_builder; | 5 library fasta.body_builder; |
6 | 6 |
7 import '../fasta_codes.dart' | 7 import '../fasta_codes.dart' |
8 show | 8 show |
9 FastaMessage, | 9 FastaMessage, |
10 codeConstFieldWithoutInitializer, | 10 codeConstFieldWithoutInitializer, |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 fileUri: error.uri); | 332 fileUri: error.uri); |
333 } | 333 } |
334 } | 334 } |
335 | 335 |
336 @override | 336 @override |
337 JumpTarget createJumpTarget(JumpTargetKind kind, int charOffset) { | 337 JumpTarget createJumpTarget(JumpTargetKind kind, int charOffset) { |
338 return new JumpTarget(kind, functionNestingLevel, member, charOffset); | 338 return new JumpTarget(kind, functionNestingLevel, member, charOffset); |
339 } | 339 } |
340 | 340 |
341 @override | 341 @override |
| 342 void beginMetadata(Token token) { |
| 343 debugEvent("beginMetadata"); |
| 344 super.push(constantExpressionRequired); |
| 345 constantExpressionRequired = true; |
| 346 } |
| 347 |
| 348 @override |
342 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { | 349 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { |
343 debugEvent("Metadata"); | 350 debugEvent("Metadata"); |
344 pop(); // Arguments. | 351 var arguments = pop(); |
345 popIfNotNull(periodBeforeName); // Postfix. | 352 if (arguments != null) { |
346 pop(); // Type arguments. | 353 endConstructorReference(beginToken, periodBeforeName, endToken); |
347 pop(); // Expression or type name (depends on arguments). | 354 push(arguments); |
348 // TODO(ahe): Implement metadata on local declarations. | 355 endNewExpression(beginToken); |
| 356 push(popForValue()); |
| 357 } else { |
| 358 var postfix = popIfNotNull(periodBeforeName); |
| 359 if (postfix != null) { |
| 360 addCompileTimeError(offsetForToken(beginToken), "Not implemented."); |
| 361 } |
| 362 pop(); // Type arguments. |
| 363 var e = popForValue(); // Expression. |
| 364 constantExpressionRequired = pop(); |
| 365 push(e); |
| 366 } |
349 } | 367 } |
350 | 368 |
351 @override | 369 @override |
352 void endMetadataStar(int count, bool forParameter) { | 370 void endMetadataStar(int count, bool forParameter) { |
353 debugEvent("MetadataStar"); | 371 debugEvent("MetadataStar"); |
354 push(NullValue.Metadata); | 372 push(popList(count) ?? NullValue.Metadata); |
355 } | 373 } |
356 | 374 |
357 @override | 375 @override |
358 void endTopLevelFields(int count, Token beginToken, Token endToken) { | 376 void endTopLevelFields(int count, Token beginToken, Token endToken) { |
359 debugEvent("TopLevelFields"); | 377 debugEvent("TopLevelFields"); |
360 doFields(count); | 378 doFields(count); |
361 // There's no metadata here because of a slight asymmetry between | |
362 // [parseTopLevelMember] and [parseMember]. This asymmetry leads to | |
363 // DietListener discarding top-level member metadata. | |
364 } | 379 } |
365 | 380 |
366 @override | 381 @override |
367 void endFields(int count, Token beginToken, Token endToken) { | 382 void endFields(int count, Token beginToken, Token endToken) { |
368 debugEvent("Fields"); | 383 debugEvent("Fields"); |
369 doFields(count); | 384 doFields(count); |
370 pop(); // Metadata. | |
371 } | 385 } |
372 | 386 |
373 void doFields(int count) { | 387 void doFields(int count) { |
| 388 List<FieldBuilder> fields = <FieldBuilder>[]; |
374 for (int i = 0; i < count; i++) { | 389 for (int i = 0; i < count; i++) { |
375 Expression initializer = pop(); | 390 Expression initializer = pop(); |
376 Identifier identifier = pop(); | 391 Identifier identifier = pop(); |
| 392 String name = identifier.name; |
| 393 FieldBuilder field; |
| 394 if (classBuilder != null) { |
| 395 field = classBuilder[name]; |
| 396 } else { |
| 397 field = library[name]; |
| 398 } |
| 399 fields.add(field); |
377 if (initializer != null) { | 400 if (initializer != null) { |
378 String name = identifier.name; | |
379 FieldBuilder field; | |
380 if (classBuilder != null) { | |
381 field = classBuilder[name]; | |
382 } else { | |
383 field = library[name]; | |
384 } | |
385 if (field.next != null) { | 401 if (field.next != null) { |
386 // TODO(ahe): This can happen, for example, if a final field is | 402 // TODO(ahe): This can happen, for example, if a final field is |
387 // combined with a setter. | 403 // combined with a setter. |
388 internalError( | 404 internalError( |
389 "Unhandled: '${field.name}' has more than one declaration."); | 405 "Unhandled: '${field.name}' has more than one declaration."); |
390 } | 406 } |
391 field.initializer = initializer; | 407 field.initializer = initializer; |
392 _typeInferrer.inferFieldInitializer(field.builtType, initializer); | 408 _typeInferrer.inferFieldInitializer(field.builtType, initializer); |
393 } | 409 } |
394 } | 410 } |
395 pop(); // Type. | 411 pop(); // Type. |
396 pop(); // Modifiers. | 412 pop(); // Modifiers. |
| 413 List annotations = pop(); |
| 414 if (annotations != null) { |
| 415 Field field = fields.first.target; |
| 416 // The first (and often only field) will not get a clone. |
| 417 annotations.forEach(field.addAnnotation); |
| 418 for (int i = 1; i < fields.length; i++) { |
| 419 // We have to clone the annotations on the remaining fields. |
| 420 field = fields[i].target; |
| 421 cloner ??= new CloneVisitor(); |
| 422 for (Expression annotation in annotations) { |
| 423 field.addAnnotation(cloner.clone(annotation)); |
| 424 } |
| 425 } |
| 426 } |
397 } | 427 } |
398 | 428 |
399 @override | 429 @override |
400 void endMember() { | 430 void endMember() { |
401 debugEvent("Member"); | 431 debugEvent("Member"); |
402 checkEmpty(-1); | 432 checkEmpty(-1); |
403 } | 433 } |
404 | 434 |
405 @override | 435 @override |
406 void endBlockFunctionBody(int count, Token beginToken, Token endToken) { | 436 void endBlockFunctionBody(int count, Token beginToken, Token endToken) { |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 DartType _computeReturnTypeContext(MemberBuilder member) { | 539 DartType _computeReturnTypeContext(MemberBuilder member) { |
510 if (member is KernelProcedureBuilder) { | 540 if (member is KernelProcedureBuilder) { |
511 return member.target.function.returnType; | 541 return member.target.function.returnType; |
512 } else { | 542 } else { |
513 assert(member is KernelConstructorBuilder); | 543 assert(member is KernelConstructorBuilder); |
514 return null; | 544 return null; |
515 } | 545 } |
516 } | 546 } |
517 | 547 |
518 @override | 548 @override |
519 void finishFunction( | 549 void finishFunction(List annotations, FormalParameters formals, |
520 FormalParameters formals, AsyncMarker asyncModifier, Statement body) { | 550 AsyncMarker asyncModifier, Statement body) { |
521 debugEvent("finishFunction"); | 551 debugEvent("finishFunction"); |
522 typePromoter.finished(); | 552 typePromoter.finished(); |
523 _typeInferrer.inferFunctionBody( | 553 _typeInferrer.inferFunctionBody( |
524 _computeReturnTypeContext(member), asyncModifier, body); | 554 _computeReturnTypeContext(member), asyncModifier, body); |
525 KernelFunctionBuilder builder = member; | 555 KernelFunctionBuilder builder = member; |
526 builder.body = body; | 556 builder.body = body; |
| 557 Member target = builder.target; |
| 558 for (Expression annotation in annotations ?? const []) { |
| 559 target.addAnnotation(annotation); |
| 560 } |
527 if (formals?.optional != null) { | 561 if (formals?.optional != null) { |
528 Iterator<FormalParameterBuilder> formalBuilders = | 562 Iterator<FormalParameterBuilder> formalBuilders = |
529 builder.formals.skip(formals.required.length).iterator; | 563 builder.formals.skip(formals.required.length).iterator; |
530 for (VariableDeclaration parameter in formals.optional.formals) { | 564 for (VariableDeclaration parameter in formals.optional.formals) { |
531 bool hasMore = formalBuilders.moveNext(); | 565 bool hasMore = formalBuilders.moveNext(); |
532 assert(hasMore); | 566 assert(hasMore); |
533 VariableDeclaration realParameter = formalBuilders.current.target; | 567 VariableDeclaration realParameter = formalBuilders.current.target; |
534 Expression initializer = | 568 Expression initializer = |
535 parameter.initializer ?? new KernelNullLiteral(); | 569 parameter.initializer ?? new KernelNullLiteral(); |
536 _typeInferrer.inferParameterInitializer( | 570 _typeInferrer.inferParameterInitializer( |
(...skipping 1667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2204 // means that it is unresolved. So we set target to null so we | 2238 // means that it is unresolved. So we set target to null so we |
2205 // can generate a no-such-method error below. | 2239 // can generate a no-such-method error below. |
2206 assert(body.isUnresolved); | 2240 assert(body.isUnresolved); |
2207 target = null; | 2241 target = null; |
2208 errorName = body.unresolvedName; | 2242 errorName = body.unresolvedName; |
2209 } | 2243 } |
2210 } | 2244 } |
2211 if (target is Constructor || | 2245 if (target is Constructor || |
2212 (target is Procedure && target.kind == ProcedureKind.Factory)) { | 2246 (target is Procedure && target.kind == ProcedureKind.Factory)) { |
2213 push(buildStaticInvocation(target, arguments, | 2247 push(buildStaticInvocation(target, arguments, |
2214 isConst: optional("const", token), | 2248 isConst: optional("const", token) || optional("@", token), |
2215 charOffset: nameToken.charOffset, | 2249 charOffset: nameToken.charOffset, |
2216 initialTarget: initialTarget)); | 2250 initialTarget: initialTarget)); |
2217 return; | 2251 return; |
2218 } else { | 2252 } else { |
2219 errorName ??= debugName(type.name, name); | 2253 errorName ??= debugName(type.name, name); |
2220 } | 2254 } |
2221 } else { | 2255 } else { |
2222 errorName = debugName(getNodeName(type), name); | 2256 errorName = debugName(getNodeName(type), name); |
2223 } | 2257 } |
2224 errorName ??= name; | 2258 errorName ??= name; |
(...skipping 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3585 if (starToken == null) { | 3619 if (starToken == null) { |
3586 return AsyncMarker.Async; | 3620 return AsyncMarker.Async; |
3587 } else { | 3621 } else { |
3588 assert(identical(starToken.stringValue, "*")); | 3622 assert(identical(starToken.stringValue, "*")); |
3589 return AsyncMarker.AsyncStar; | 3623 return AsyncMarker.AsyncStar; |
3590 } | 3624 } |
3591 } else { | 3625 } else { |
3592 return internalError("Unknown async modifier: $asyncToken"); | 3626 return internalError("Unknown async modifier: $asyncToken"); |
3593 } | 3627 } |
3594 } | 3628 } |
OLD | NEW |