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 FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; | 8 show |
| 9 FastaMessage, |
| 10 codeConstFieldWithoutInitializer, |
| 11 codeExpectedButGot, |
| 12 codeExpectedFunctionBody, |
| 13 codeFinalFieldWithoutInitializer; |
9 | 14 |
10 import '../parser/parser.dart' | 15 import '../parser/parser.dart' |
11 show Assert, FormalParameterType, MemberKind, optional; | 16 show Assert, FormalParameterType, MemberKind, optional; |
12 | 17 |
13 import '../parser/identifier_context.dart' show IdentifierContext; | 18 import '../parser/identifier_context.dart' show IdentifierContext; |
14 | 19 |
15 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; | 20 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; |
16 | 21 |
17 import 'package:front_end/src/fasta/kernel/utils.dart' show offsetForToken; | 22 import 'package:front_end/src/fasta/kernel/utils.dart' show offsetForToken; |
18 | 23 |
(...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 | 983 |
979 /// Look up [name] in [scope] using [token] as location information (both to | 984 /// Look up [name] in [scope] using [token] as location information (both to |
980 /// report problems and as the file offset in the generated kernel code). | 985 /// report problems and as the file offset in the generated kernel code). |
981 /// [isQualified] should be true if [name] is a qualified access | 986 /// [isQualified] should be true if [name] is a qualified access |
982 /// (which implies that it shouldn't be turned into a [ThisPropertyAccessor] | 987 /// (which implies that it shouldn't be turned into a [ThisPropertyAccessor] |
983 /// if the name doesn't resolve in the scope). | 988 /// if the name doesn't resolve in the scope). |
984 @override | 989 @override |
985 scopeLookup(Scope scope, String name, Token token, | 990 scopeLookup(Scope scope, String name, Token token, |
986 {bool isQualified: false, PrefixBuilder prefix}) { | 991 {bool isQualified: false, PrefixBuilder prefix}) { |
987 Builder builder = scope.lookup(name, offsetForToken(token), uri); | 992 Builder builder = scope.lookup(name, offsetForToken(token), uri); |
| 993 if (builder != null && member.isField && builder.isInstanceMember) { |
| 994 return new IncompleteError(this, token, |
| 995 "Can't access 'this' in a field initializer to read '$name'."); |
| 996 } |
988 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { | 997 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { |
989 Name n = new Name(name, library.library); | 998 Name n = new Name(name, library.library); |
990 if (prefix != null && | 999 if (prefix != null && |
991 prefix.deferred && | 1000 prefix.deferred && |
992 builder == null && | 1001 builder == null && |
993 "loadLibrary" == name) { | 1002 "loadLibrary" == name) { |
994 return buildCompileTimeError( | 1003 return buildCompileTimeError( |
995 "Deferred loading isn't implemented yet.", offsetForToken(token)); | 1004 "Deferred loading isn't implemented yet.", offsetForToken(token)); |
996 } else if (!isQualified && isInstanceContext) { | 1005 } else if (!isQualified && isInstanceContext) { |
997 assert(builder == null); | 1006 assert(builder == null); |
998 if (constantExpressionRequired) { | 1007 if (constantExpressionRequired || member.isField) { |
999 return new UnresolvedAccessor(this, n, token); | 1008 return new UnresolvedAccessor(this, n, token); |
1000 } | 1009 } |
1001 return new ThisPropertyAccessor(this, token, n, null, null); | 1010 return new ThisPropertyAccessor(this, token, n, null, null); |
1002 } else if (isBuiltinLibrary && | 1011 } else if (isBuiltinLibrary && |
1003 name == "main" && | 1012 name == "main" && |
1004 member?.name == "_getMainClosure") { | 1013 member?.name == "_getMainClosure") { |
1005 // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 | 1014 // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 |
1006 return new KernelNullLiteral()..fileOffset = offsetForToken(token); | 1015 return new KernelNullLiteral()..fileOffset = offsetForToken(token); |
1007 } else { | 1016 } else { |
1008 return new UnresolvedAccessor(this, n, token); | 1017 return new UnresolvedAccessor(this, n, token); |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1283 void endFieldInitializer(Token assignmentOperator, Token token) { | 1292 void endFieldInitializer(Token assignmentOperator, Token token) { |
1284 debugEvent("FieldInitializer"); | 1293 debugEvent("FieldInitializer"); |
1285 assert(assignmentOperator.stringValue == "="); | 1294 assert(assignmentOperator.stringValue == "="); |
1286 push(popForValue()); | 1295 push(popForValue()); |
1287 } | 1296 } |
1288 | 1297 |
1289 @override | 1298 @override |
1290 void handleNoFieldInitializer(Token token) { | 1299 void handleNoFieldInitializer(Token token) { |
1291 debugEvent("NoFieldInitializer"); | 1300 debugEvent("NoFieldInitializer"); |
1292 if (constantExpressionRequired) { | 1301 if (constantExpressionRequired) { |
1293 addCompileTimeError( | |
1294 token.charOffset, "const field must have initializer."); | |
1295 // Creating a null value to prevent the Dart VM from crashing. | 1302 // Creating a null value to prevent the Dart VM from crashing. |
1296 push(new KernelNullLiteral()..fileOffset = offsetForToken(token)); | 1303 push(new KernelNullLiteral()..fileOffset = offsetForToken(token)); |
1297 } else { | 1304 } else { |
1298 push(NullValue.FieldInitializer); | 1305 push(NullValue.FieldInitializer); |
1299 } | 1306 } |
1300 } | 1307 } |
1301 | 1308 |
1302 @override | 1309 @override |
1303 void endInitializedIdentifier(Token nameToken) { | 1310 void endInitializedIdentifier(Token nameToken) { |
1304 // TODO(ahe): Use [InitializedIdentifier] here? | 1311 // TODO(ahe): Use [InitializedIdentifier] here? |
(...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2819 | 2826 |
2820 @override | 2827 @override |
2821 void handleModifiers(int count) { | 2828 void handleModifiers(int count) { |
2822 debugEvent("Modifiers"); | 2829 debugEvent("Modifiers"); |
2823 // TODO(ahe): Copied from outline_builder.dart. | 2830 // TODO(ahe): Copied from outline_builder.dart. |
2824 push(popList(count) ?? NullValue.Modifiers); | 2831 push(popList(count) ?? NullValue.Modifiers); |
2825 } | 2832 } |
2826 | 2833 |
2827 @override | 2834 @override |
2828 void handleRecoverableError(Token token, FastaMessage message) { | 2835 void handleRecoverableError(Token token, FastaMessage message) { |
2829 bool silent = hasParserError; | 2836 bool silent = hasParserError || |
| 2837 message.code == codeFinalFieldWithoutInitializer || |
| 2838 message.code == codeConstFieldWithoutInitializer; |
2830 addCompileTimeError(message.charOffset, message.message, silent: silent); | 2839 addCompileTimeError(message.charOffset, message.message, silent: silent); |
2831 } | 2840 } |
2832 | 2841 |
2833 @override | 2842 @override |
2834 Token handleUnrecoverableError(Token token, FastaMessage message) { | 2843 Token handleUnrecoverableError(Token token, FastaMessage message) { |
2835 if (enableNative && message.code == codeExpectedFunctionBody) { | 2844 if (enableNative && message.code == codeExpectedFunctionBody) { |
2836 Token recover = library.loader.target.skipNativeClause(token); | 2845 Token recover = library.loader.target.skipNativeClause(token); |
2837 if (recover != null) return recover; | 2846 if (recover != null) return recover; |
2838 } else if (message.code == codeExpectedButGot) { | 2847 } else if (message.code == codeExpectedButGot) { |
2839 String expected = message.arguments["string"]; | 2848 String expected = message.arguments["string"]; |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3542 if (starToken == null) { | 3551 if (starToken == null) { |
3543 return AsyncMarker.Async; | 3552 return AsyncMarker.Async; |
3544 } else { | 3553 } else { |
3545 assert(identical(starToken.stringValue, "*")); | 3554 assert(identical(starToken.stringValue, "*")); |
3546 return AsyncMarker.AsyncStar; | 3555 return AsyncMarker.AsyncStar; |
3547 } | 3556 } |
3548 } else { | 3557 } else { |
3549 return internalError("Unknown async modifier: $asyncToken"); | 3558 return internalError("Unknown async modifier: $asyncToken"); |
3550 } | 3559 } |
3551 } | 3560 } |
OLD | NEW |