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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 getRedirectionTarget; | 71 getRedirectionTarget; |
72 | 72 |
73 import 'kernel_builder.dart'; | 73 import 'kernel_builder.dart'; |
74 | 74 |
75 import '../names.dart'; | 75 import '../names.dart'; |
76 | 76 |
77 class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { | 77 class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
78 @override | 78 @override |
79 final KernelLibraryBuilder library; | 79 final KernelLibraryBuilder library; |
80 | 80 |
81 final MemberBuilder member; | 81 final ModifierBuilder member; |
82 | 82 |
83 final KernelClassBuilder classBuilder; | 83 final KernelClassBuilder classBuilder; |
84 | 84 |
85 final ClassHierarchy hierarchy; | 85 final ClassHierarchy hierarchy; |
86 | 86 |
87 final CoreTypes coreTypes; | 87 final CoreTypes coreTypes; |
88 | 88 |
89 final bool isInstanceMember; | 89 final bool isInstanceMember; |
90 | 90 |
91 final Scope enclosingScope; | 91 final Scope enclosingScope; |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 void beginMetadata(Token token) { | 342 void beginMetadata(Token token) { |
343 debugEvent("beginMetadata"); | 343 debugEvent("beginMetadata"); |
344 super.push(constantExpressionRequired); | 344 super.push(constantExpressionRequired); |
345 constantExpressionRequired = true; | 345 constantExpressionRequired = true; |
346 } | 346 } |
347 | 347 |
348 @override | 348 @override |
349 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { | 349 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { |
350 debugEvent("Metadata"); | 350 debugEvent("Metadata"); |
351 var arguments = pop(); | 351 var arguments = pop(); |
| 352 pushQualifiedReference(beginToken.next, periodBeforeName); |
352 if (arguments != null) { | 353 if (arguments != null) { |
353 endConstructorReference(beginToken, periodBeforeName, endToken); | |
354 push(arguments); | 354 push(arguments); |
355 endNewExpression(beginToken); | 355 endNewExpression(beginToken); |
356 push(popForValue()); | 356 push(popForValue()); |
357 } else { | 357 } else { |
358 var postfix = popIfNotNull(periodBeforeName); | 358 String name = pop(); |
359 if (postfix != null) { | 359 pop(); // Type arguments (ignored, already reported by parser). |
360 addCompileTimeError(offsetForToken(beginToken), "Not implemented."); | 360 var expression = pop(); |
| 361 if (expression is Identifier) { |
| 362 Identifier identifier = expression; |
| 363 expression = new UnresolvedAccessor( |
| 364 this, new Name(identifier.name, library.library), identifier.token); |
361 } | 365 } |
362 pop(); // Type arguments. | 366 if (name?.isNotEmpty ?? false) { |
363 var e = popForValue(); // Expression. | 367 Token period = periodBeforeName ?? beginToken.next; |
364 constantExpressionRequired = pop(); | 368 FastaAccessor accessor = expression; |
365 push(e); | 369 expression = accessor.buildPropertyAccess( |
| 370 new IncompletePropertyAccessor( |
| 371 this, period.next, new Name(name, library.library)), |
| 372 period.next.offset, |
| 373 false); |
| 374 } |
| 375 |
| 376 bool savedConstantExpressionRequired = pop(); |
| 377 if (expression is! StaticAccessor) { |
| 378 push(wrapInCompileTimeError( |
| 379 toValue(expression), |
| 380 "This can't be used as metadata; metadata should be a reference to " |
| 381 "a compile-time constant variable, or " |
| 382 "a call to a constant constructor.")); |
| 383 } else { |
| 384 push(toValue(expression)); |
| 385 } |
| 386 constantExpressionRequired = savedConstantExpressionRequired; |
366 } | 387 } |
367 } | 388 } |
368 | 389 |
369 @override | 390 @override |
370 void endMetadataStar(int count, bool forParameter) { | 391 void endMetadataStar(int count, bool forParameter) { |
371 debugEvent("MetadataStar"); | 392 debugEvent("MetadataStar"); |
372 push(popList(count) ?? NullValue.Metadata); | 393 push(popList(count) ?? NullValue.Metadata); |
373 } | 394 } |
374 | 395 |
375 @override | 396 @override |
(...skipping 1640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2016 this, token, accessor, incrementOperator(token), null)); | 2037 this, token, accessor, incrementOperator(token), null)); |
2017 } else { | 2038 } else { |
2018 push(wrapInCompileTimeError(toValue(accessor), "Can't assign to this.")); | 2039 push(wrapInCompileTimeError(toValue(accessor), "Can't assign to this.")); |
2019 } | 2040 } |
2020 } | 2041 } |
2021 | 2042 |
2022 @override | 2043 @override |
2023 void endConstructorReference( | 2044 void endConstructorReference( |
2024 Token start, Token periodBeforeName, Token endToken) { | 2045 Token start, Token periodBeforeName, Token endToken) { |
2025 debugEvent("ConstructorReference"); | 2046 debugEvent("ConstructorReference"); |
2026 // A constructor reference can contain up to three identifiers: | 2047 pushQualifiedReference(start, periodBeforeName); |
2027 // | 2048 } |
2028 // a) type <type-arguments>? | 2049 |
2029 // b) type <type-arguments>? . name | 2050 /// A qualfied reference is something that matches one of: |
2030 // c) prefix . type <type-arguments>? | 2051 /// |
2031 // d) prefix . type <type-arguments>? . name | 2052 /// identifier |
2032 // | 2053 /// identifier typeArguments? '.' identifier |
2033 // This isn't a legal constructor reference: | 2054 /// identifier '.' identifier typeArguments? '.' identifier |
2034 // | 2055 /// |
2035 // type . name <type-arguments> | 2056 /// That is, one to three identifiers separated by periods and optionally one |
2036 // | 2057 /// list of type arguments. |
2037 // But the parser can't tell this from type c) above. | 2058 /// |
2038 // | 2059 /// A qualified reference can be used to represent both a reference to |
2039 // This method pops 2 (or 3 if periodBeforeName != null) values from the | 2060 /// compile-time constant variable (metadata) or a constructor reference |
2040 // stack and pushes 3 values: a type, a list of type arguments, and a name. | 2061 /// (used by metadata, new/const expression, and redirecting factories). |
2041 // | 2062 /// |
2042 // If the constructor reference can be resolved, type is either a | 2063 /// Note that the parser will report errors if metadata includes type |
2043 // ClassBuilder, or a ThisPropertyAccessor. Otherwise, it's an error that | 2064 /// arguments, but will other preserve them for error recovery. |
2044 // should be handled later. | 2065 /// |
| 2066 /// A constructor reference can contain up to three identifiers: |
| 2067 /// |
| 2068 /// a) type typeArguments? |
| 2069 /// b) type typeArguments? '.' name |
| 2070 /// c) prefix '.' type typeArguments? |
| 2071 /// d) prefix '.' type typeArguments? '.' name |
| 2072 /// |
| 2073 /// This isn't a legal constructor reference: |
| 2074 /// |
| 2075 /// type '.' name typeArguments? |
| 2076 /// |
| 2077 /// But the parser can't tell this from type c) above. |
| 2078 /// |
| 2079 /// This method pops 2 (or 3 if `periodBeforeName != null`) values from the |
| 2080 /// stack and pushes 3 values: an accessor (the type in a constructor |
| 2081 /// reference, or an expression in metadata), a list of type arguments, and a |
| 2082 /// name. |
| 2083 void pushQualifiedReference(Token start, Token periodBeforeName) { |
2045 Identifier suffix = popIfNotNull(periodBeforeName); | 2084 Identifier suffix = popIfNotNull(periodBeforeName); |
2046 Identifier identifier; | 2085 Identifier identifier; |
2047 List<DartType> typeArguments = pop(); | 2086 List<DartType> typeArguments = pop(); |
2048 dynamic type = pop(); | 2087 dynamic type = pop(); |
2049 if (type is List) { | 2088 if (type is List) { |
2050 var prefix = type[0]; | 2089 var prefix = type[0]; |
2051 identifier = type[1]; | 2090 identifier = type[1]; |
2052 if (prefix is PrefixBuilder) { | 2091 if (prefix is PrefixBuilder) { |
2053 type = scopeLookup(prefix.exports, identifier.name, start, | 2092 type = scopeLookup(prefix.exports, identifier.name, start, |
2054 isQualified: true, prefix: prefix); | 2093 isQualified: true, prefix: prefix); |
(...skipping 1564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3619 if (starToken == null) { | 3658 if (starToken == null) { |
3620 return AsyncMarker.Async; | 3659 return AsyncMarker.Async; |
3621 } else { | 3660 } else { |
3622 assert(identical(starToken.stringValue, "*")); | 3661 assert(identical(starToken.stringValue, "*")); |
3623 return AsyncMarker.AsyncStar; | 3662 return AsyncMarker.AsyncStar; |
3624 } | 3663 } |
3625 } else { | 3664 } else { |
3626 return internalError("Unknown async modifier: $asyncToken"); | 3665 return internalError("Unknown async modifier: $asyncToken"); |
3627 } | 3666 } |
3628 } | 3667 } |
OLD | NEW |