Chromium Code Reviews| 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 FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; |
| 9 | 9 |
| 10 import '../parser/parser.dart' | 10 import '../parser/parser.dart' |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 Block block = popBlock(count, beginToken); | 403 Block block = popBlock(count, beginToken); |
| 404 exitLocalScope(); | 404 exitLocalScope(); |
| 405 push(block); | 405 push(block); |
| 406 } | 406 } |
| 407 } | 407 } |
| 408 | 408 |
| 409 void prepareInitializers() { | 409 void prepareInitializers() { |
| 410 ProcedureBuilder member = this.member; | 410 ProcedureBuilder member = this.member; |
| 411 scope = member.computeFormalParameterInitializerScope(scope); | 411 scope = member.computeFormalParameterInitializerScope(scope); |
| 412 if (member is KernelConstructorBuilder) { | 412 if (member is KernelConstructorBuilder) { |
| 413 if (member.isConst && | |
| 414 (classBuilder.cls.superclass?.isMixinApplication ?? false)) { | |
| 415 addCompileTimeError(member.charOffset, | |
| 416 "Can't extend a mixin application and be 'const'."); | |
| 417 } | |
| 413 if (member.formals != null) { | 418 if (member.formals != null) { |
| 414 for (KernelFormalParameterBuilder formal in member.formals) { | 419 for (KernelFormalParameterBuilder formal in member.formals) { |
| 415 if (formal.hasThis) { | 420 if (formal.hasThis) { |
| 416 Initializer initializer; | 421 Initializer initializer; |
| 417 if (member.isExternal) { | 422 if (member.isExternal) { |
| 418 initializer = buildInvalidInitializer( | 423 initializer = buildInvalidInitializer( |
| 419 buildCompileTimeError( | 424 buildCompileTimeError( |
| 420 "An external constructor can't initialize fields.", | 425 "An external constructor can't initialize fields.", |
| 421 formal.charOffset), | 426 formal.charOffset), |
| 422 formal.charOffset); | 427 formal.charOffset); |
| (...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1207 @override | 1212 @override |
| 1208 void endVariableInitializer(Token assignmentOperator) { | 1213 void endVariableInitializer(Token assignmentOperator) { |
| 1209 debugEvent("VariableInitializer"); | 1214 debugEvent("VariableInitializer"); |
| 1210 assert(assignmentOperator.stringValue == "="); | 1215 assert(assignmentOperator.stringValue == "="); |
| 1211 pushNewLocalVariable(popForValue(), equalsToken: assignmentOperator); | 1216 pushNewLocalVariable(popForValue(), equalsToken: assignmentOperator); |
| 1212 } | 1217 } |
| 1213 | 1218 |
| 1214 @override | 1219 @override |
| 1215 void handleNoVariableInitializer(Token token) { | 1220 void handleNoVariableInitializer(Token token) { |
| 1216 debugEvent("NoVariableInitializer"); | 1221 debugEvent("NoVariableInitializer"); |
| 1217 pushNewLocalVariable(null); | 1222 bool isConst = (currentLocalVariableModifiers & constMask) != 0; |
| 1223 bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; | |
| 1224 Expression initializer; | |
| 1225 if (!optional("in", token)) { | |
| 1226 // A for-in loop-variable can't have an initializer. So let's remain | |
| 1227 // silent if the next token is `in`. Since a for-in loop can only have | |
| 1228 // one variable it must be followed by `in`. | |
| 1229 if (isConst) { | |
| 1230 initializer = buildCompileTimeError( | |
| 1231 "A 'const' variable must be initialized.", token.charOffset); | |
| 1232 } else if (isFinal) { | |
| 1233 initializer = buildCompileTimeError( | |
| 1234 "A 'final' variable must be initialized.", token.charOffset); | |
| 1235 } | |
| 1236 } | |
| 1237 pushNewLocalVariable(initializer); | |
| 1218 } | 1238 } |
| 1219 | 1239 |
| 1220 void pushNewLocalVariable(Expression initializer, {Token equalsToken}) { | 1240 void pushNewLocalVariable(Expression initializer, {Token equalsToken}) { |
| 1221 Identifier identifier = pop(); | 1241 Identifier identifier = pop(); |
| 1222 assert(currentLocalVariableModifiers != -1); | 1242 assert(currentLocalVariableModifiers != -1); |
| 1223 bool isConst = (currentLocalVariableModifiers & constMask) != 0; | 1243 bool isConst = (currentLocalVariableModifiers & constMask) != 0; |
| 1224 bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; | 1244 bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; |
| 1225 assert(isConst == constantExpressionRequired); | 1245 assert(isConst == constantExpressionRequired); |
| 1226 push(new KernelVariableDeclaration(identifier.name, functionNestingLevel, | 1246 push(new KernelVariableDeclaration(identifier.name, functionNestingLevel, |
| 1227 initializer: initializer, | 1247 initializer: initializer, |
| (...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1974 List<TypeParameter> typeParameters = target.function.typeParameters; | 1994 List<TypeParameter> typeParameters = target.function.typeParameters; |
| 1975 if (target is Constructor) { | 1995 if (target is Constructor) { |
| 1976 assert(!target.enclosingClass.isAbstract); | 1996 assert(!target.enclosingClass.isAbstract); |
| 1977 typeParameters = target.enclosingClass.typeParameters; | 1997 typeParameters = target.enclosingClass.typeParameters; |
| 1978 } | 1998 } |
| 1979 if (!checkArguments(target.function, arguments, typeParameters)) { | 1999 if (!checkArguments(target.function, arguments, typeParameters)) { |
| 1980 return throwNoSuchMethodError(new NullLiteral()..fileOffset = charOffset, | 2000 return throwNoSuchMethodError(new NullLiteral()..fileOffset = charOffset, |
| 1981 target.name.name, arguments, charOffset); | 2001 target.name.name, arguments, charOffset); |
| 1982 } | 2002 } |
| 1983 if (target is Constructor) { | 2003 if (target is Constructor) { |
| 2004 if (isConst && !target.isConst) { | |
| 2005 return buildCompileTimeError("Not a const constructor.", charOffset); | |
| 2006 } | |
| 1984 return new KernelConstructorInvocation(target, initialTarget, arguments, | 2007 return new KernelConstructorInvocation(target, initialTarget, arguments, |
| 1985 isConst: isConst) | 2008 isConst: isConst) |
| 1986 ..fileOffset = charOffset; | 2009 ..fileOffset = charOffset; |
| 1987 } else if (target is Procedure && target.kind == ProcedureKind.Factory) { | 2010 } else if (target is Procedure && target.kind == ProcedureKind.Factory) { |
| 1988 return new KernelFactoryConstructorInvocation( | 2011 return new KernelFactoryConstructorInvocation( |
| 1989 target, initialTarget, arguments, | 2012 target, initialTarget, arguments, |
| 1990 isConst: isConst) | 2013 isConst: isConst) |
| 1991 ..fileOffset = charOffset; | 2014 ..fileOffset = charOffset; |
| 1992 } else { | 2015 } else { |
| 2016 Procedure factory = target; | |
|
Johnni Winther
2017/06/12 07:46:16
Shouldn't this be in the if branch above?
ahe
2017/06/12 08:13:22
Yes, good catch!
This is a merge problem. Paul ad
| |
| 2017 if (isConst && !factory.isConst) { | |
| 2018 return buildCompileTimeError("Not a const factory.", charOffset); | |
| 2019 } | |
| 1993 return new KernelStaticInvocation(target, arguments, isConst: isConst) | 2020 return new KernelStaticInvocation(target, arguments, isConst: isConst) |
| 1994 ..fileOffset = charOffset; | 2021 ..fileOffset = charOffset; |
| 1995 } | 2022 } |
| 1996 } | 2023 } |
| 1997 | 2024 |
| 1998 @override | 2025 @override |
| 1999 bool checkArguments(FunctionNode function, Arguments arguments, | 2026 bool checkArguments(FunctionNode function, Arguments arguments, |
| 2000 List<TypeParameter> typeParameters) { | 2027 List<TypeParameter> typeParameters) { |
| 2001 if (arguments.positional.length < function.requiredParameterCount || | 2028 if (arguments.positional.length < function.requiredParameterCount || |
| 2002 arguments.positional.length > function.positionalParameters.length) { | 2029 arguments.positional.length > function.positionalParameters.length) { |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2334 JumpTarget breakTarget = exitBreakTarget(); | 2361 JumpTarget breakTarget = exitBreakTarget(); |
| 2335 if (continueTarget.hasUsers) { | 2362 if (continueTarget.hasUsers) { |
| 2336 body = new LabeledStatement(body); | 2363 body = new LabeledStatement(body); |
| 2337 continueTarget.resolveContinues(body); | 2364 continueTarget.resolveContinues(body); |
| 2338 } | 2365 } |
| 2339 VariableDeclaration variable; | 2366 VariableDeclaration variable; |
| 2340 bool declaresVariable = false; | 2367 bool declaresVariable = false; |
| 2341 if (lvalue is VariableDeclaration) { | 2368 if (lvalue is VariableDeclaration) { |
| 2342 declaresVariable = true; | 2369 declaresVariable = true; |
| 2343 variable = lvalue; | 2370 variable = lvalue; |
| 2371 if (variable.isConst) { | |
| 2372 addCompileTimeError( | |
| 2373 variable.fileOffset, "A for-in loop-variable can't be 'const'."); | |
| 2374 } | |
| 2344 } else if (lvalue is FastaAccessor) { | 2375 } else if (lvalue is FastaAccessor) { |
| 2345 /// We are in this case, where `lvalue` isn't a [VariableDeclaration]: | 2376 /// We are in this case, where `lvalue` isn't a [VariableDeclaration]: |
| 2346 /// | 2377 /// |
| 2347 /// for (lvalue in expression) body | 2378 /// for (lvalue in expression) body |
| 2348 /// | 2379 /// |
| 2349 /// This is normalized to: | 2380 /// This is normalized to: |
| 2350 /// | 2381 /// |
| 2351 /// for (final #t in expression) { | 2382 /// for (final #t in expression) { |
| 2352 /// lvalue = #t; | 2383 /// lvalue = #t; |
| 2353 /// body; | 2384 /// body; |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2881 buildCompileTimeError( | 2912 buildCompileTimeError( |
| 2882 "'$name' isn't an instance field of this class.", offset), | 2913 "'$name' isn't an instance field of this class.", offset), |
| 2883 offset); | 2914 offset); |
| 2884 } | 2915 } |
| 2885 } | 2916 } |
| 2886 | 2917 |
| 2887 @override | 2918 @override |
| 2888 Initializer buildSuperInitializer( | 2919 Initializer buildSuperInitializer( |
| 2889 Constructor constructor, Arguments arguments, | 2920 Constructor constructor, Arguments arguments, |
| 2890 [int charOffset = -1]) { | 2921 [int charOffset = -1]) { |
| 2922 if (member.isConst && !constructor.isConst) { | |
| 2923 return buildInvalidInitializer( | |
| 2924 buildCompileTimeError("Super constructor isn't const.", charOffset), | |
| 2925 charOffset); | |
| 2926 } | |
| 2891 needsImplicitSuperInitializer = false; | 2927 needsImplicitSuperInitializer = false; |
| 2892 return new SuperInitializer(constructor, arguments) | 2928 return new SuperInitializer(constructor, arguments) |
| 2893 ..fileOffset = charOffset; | 2929 ..fileOffset = charOffset; |
| 2894 } | 2930 } |
| 2895 | 2931 |
| 2896 @override | 2932 @override |
| 2897 Initializer buildRedirectingInitializer( | 2933 Initializer buildRedirectingInitializer( |
| 2898 Constructor constructor, Arguments arguments, | 2934 Constructor constructor, Arguments arguments, |
| 2899 [int charOffset = -1]) { | 2935 [int charOffset = -1]) { |
| 2900 needsImplicitSuperInitializer = false; | 2936 needsImplicitSuperInitializer = false; |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3475 if (starToken == null) { | 3511 if (starToken == null) { |
| 3476 return AsyncMarker.Async; | 3512 return AsyncMarker.Async; |
| 3477 } else { | 3513 } else { |
| 3478 assert(identical(starToken.stringValue, "*")); | 3514 assert(identical(starToken.stringValue, "*")); |
| 3479 return AsyncMarker.AsyncStar; | 3515 return AsyncMarker.AsyncStar; |
| 3480 } | 3516 } |
| 3481 } else { | 3517 } else { |
| 3482 return internalError("Unknown async modifier: $asyncToken"); | 3518 return internalError("Unknown async modifier: $asyncToken"); |
| 3483 } | 3519 } |
| 3484 } | 3520 } |
| OLD | NEW |