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 '../parser/parser.dart' show FormalParameterType, optional; | 7 import '../parser/parser.dart' show FormalParameterType, optional; |
8 | 8 |
9 import '../parser/error_kind.dart' show ErrorKind; | 9 import '../parser/error_kind.dart' show ErrorKind; |
10 | 10 |
(...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1386 int charOffset = thisKeyword?.charOffset; | 1386 int charOffset = thisKeyword?.charOffset; |
1387 if (thisKeyword != null) { | 1387 if (thisKeyword != null) { |
1388 if (!inConstructor) { | 1388 if (!inConstructor) { |
1389 addCompileTimeError(thisKeyword.charOffset, | 1389 addCompileTimeError(thisKeyword.charOffset, |
1390 "'this' parameters can only be used on constructors."); | 1390 "'this' parameters can only be used on constructors."); |
1391 thisKeyword = null; | 1391 thisKeyword = null; |
1392 } | 1392 } |
1393 } | 1393 } |
1394 Identifier name = pop(); | 1394 Identifier name = pop(); |
1395 DartType type = pop(); | 1395 DartType type = pop(); |
1396 pop(); // Modifiers. | 1396 int modifiers = Modifier.validate(pop()); |
| 1397 if (inCatchClause) { |
| 1398 modifiers |= finalMask; |
| 1399 } |
| 1400 bool isConst = (modifiers & constMask) != 0; |
| 1401 bool isFinal = (modifiers & finalMask) != 0; |
1397 ignore(Unhandled.Metadata); | 1402 ignore(Unhandled.Metadata); |
1398 VariableDeclaration variable; | 1403 VariableDeclaration variable; |
1399 if (!inCatchClause && functionNestingLevel == 0) { | 1404 if (!inCatchClause && functionNestingLevel == 0) { |
1400 dynamic builder = formalParameterScope.lookup(name.name, charOffset, uri); | 1405 dynamic builder = formalParameterScope.lookup(name.name, charOffset, uri); |
1401 if (builder == null) { | 1406 if (builder == null) { |
1402 if (thisKeyword == null) { | 1407 if (thisKeyword == null) { |
1403 internalError("Internal error: formal missing for '${name.name}'"); | 1408 internalError("Internal error: formal missing for '${name.name}'"); |
1404 } else { | 1409 } else { |
1405 addCompileTimeError(thisKeyword.charOffset, | 1410 addCompileTimeError(thisKeyword.charOffset, |
1406 "'${name.name}' isn't a field in this class."); | 1411 "'${name.name}' isn't a field in this class."); |
1407 thisKeyword = null; | 1412 thisKeyword = null; |
1408 } | 1413 } |
1409 } else if (thisKeyword == null) { | 1414 } else if (thisKeyword == null) { |
1410 variable = builder.build(library); | 1415 variable = builder.build(library); |
1411 variable.initializer = name.initializer; | 1416 variable.initializer = name.initializer; |
1412 } else if (builder.isField && builder.parent == classBuilder) { | 1417 } else if (builder.isField && builder.parent == classBuilder) { |
1413 FieldBuilder field = builder; | 1418 FieldBuilder field = builder; |
1414 if (type != null) { | 1419 if (type != null) { |
1415 nit("Ignoring type on 'this' parameter '${name.name}'.", | 1420 nit("Ignoring type on 'this' parameter '${name.name}'.", |
1416 thisKeyword.charOffset); | 1421 thisKeyword.charOffset); |
1417 } | 1422 } |
1418 type = field.target.type ?? const DynamicType(); | 1423 type = field.target.type ?? const DynamicType(); |
1419 variable = new VariableDeclaration(name.name, | 1424 variable = new VariableDeclaration(name.name, |
1420 type: type, initializer: name.initializer); | 1425 type: type, |
| 1426 initializer: name.initializer, |
| 1427 isFinal: isFinal, |
| 1428 isConst: isConst)..fileOffset = name.fileOffset; |
1421 } else { | 1429 } else { |
1422 addCompileTimeError( | 1430 addCompileTimeError( |
1423 name.fileOffset, "'${name.name}' isn't a field in this class."); | 1431 name.fileOffset, "'${name.name}' isn't a field in this class."); |
1424 } | 1432 } |
1425 } | 1433 } |
1426 variable ??= new VariableDeclaration(name.name, | 1434 variable ??= new VariableDeclaration(name.name, |
1427 type: type ?? const DynamicType(), | 1435 type: type ?? const DynamicType(), |
1428 initializer: name.initializer)..fileOffset = name.fileOffset; | 1436 initializer: name.initializer, |
| 1437 isFinal: isFinal, |
| 1438 isConst: isConst)..fileOffset = name.fileOffset; |
1429 push(variable); | 1439 push(variable); |
1430 } | 1440 } |
1431 | 1441 |
1432 @override | 1442 @override |
1433 void endOptionalFormalParameters( | 1443 void endOptionalFormalParameters( |
1434 int count, Token beginToken, Token endToken) { | 1444 int count, Token beginToken, Token endToken) { |
1435 debugEvent("OptionalFormalParameters"); | 1445 debugEvent("OptionalFormalParameters"); |
1436 FormalParameterType kind = optional("{", beginToken) | 1446 FormalParameterType kind = optional("{", beginToken) |
1437 ? FormalParameterType.NAMED | 1447 ? FormalParameterType.NAMED |
1438 : FormalParameterType.POSITIONAL; | 1448 : FormalParameterType.POSITIONAL; |
(...skipping 1447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2886 } else if (node is PrefixBuilder) { | 2896 } else if (node is PrefixBuilder) { |
2887 return node.name; | 2897 return node.name; |
2888 } else if (node is ThisAccessor) { | 2898 } else if (node is ThisAccessor) { |
2889 return node.isSuper ? "super" : "this"; | 2899 return node.isSuper ? "super" : "this"; |
2890 } else if (node is BuilderAccessor) { | 2900 } else if (node is BuilderAccessor) { |
2891 return node.plainNameForRead; | 2901 return node.plainNameForRead; |
2892 } else { | 2902 } else { |
2893 return internalError("Unhandled: ${node.runtimeType}"); | 2903 return internalError("Unhandled: ${node.runtimeType}"); |
2894 } | 2904 } |
2895 } | 2905 } |
OLD | NEW |