@@ -255,7 +255,7 @@ private void checkForbiddenName(String id, ExprContext context) {
255
255
}
256
256
if (context == ExprContext .Delete ) {
257
257
if (id .equals ("__debug__" )) {
258
- errorCallback .onError (ErrorCallback .ErrorType .Syntax , unit .currentLocation , "cannot assign to __debug__" );
258
+ errorCallback .onError (ErrorCallback .ErrorType .Syntax , unit .currentLocation , "cannot delete __debug__" );
259
259
}
260
260
}
261
261
}
@@ -547,7 +547,7 @@ private void collectIntoArray(ExprTy[] nodes, int bits, int alreadyOnStack) {
547
547
if (e instanceof ExprTy .Starred ) {
548
548
// splat
549
549
collector .flushStackIfNecessary ();
550
- e .accept (this );
550
+ (( ExprTy . Starred ) e ). value .accept (this );
551
551
collector .appendCollection ();
552
552
} else {
553
553
e .accept (this );
@@ -584,7 +584,21 @@ private void collectIntoDict(ExprTy[] keys, ExprTy[] values) {
584
584
collector .finishCollection ();
585
585
}
586
586
587
+ private void validateKeywords (KeywordTy [] keywords ) {
588
+ for (int i = 0 ; i < keywords .length ; i ++) {
589
+ if (keywords [i ].arg != null ) {
590
+ checkForbiddenName (keywords [i ].arg , ExprContext .Store );
591
+ for (int j = i + 1 ; j < keywords .length ; j ++) {
592
+ if (keywords [i ].arg .equals (keywords [j ].arg )) {
593
+ errorCallback .onError (ErrorCallback .ErrorType .Syntax , unit .currentLocation , "keyword argument repeated: " + keywords [i ].arg );
594
+ }
595
+ }
596
+ }
597
+ }
598
+ }
599
+
587
600
private void collectKeywords (KeywordTy [] keywords , OpCodes callOp ) {
601
+ validateKeywords (keywords );
588
602
boolean hasSplat = false ;
589
603
for (KeywordTy k : keywords ) {
590
604
if (k .arg == null ) {
@@ -751,7 +765,7 @@ public Void visit(ExprTy.Await node) {
751
765
errorCallback .onError (ErrorCallback .ErrorType .Syntax , unit .currentLocation , "'await' outside function" );
752
766
}
753
767
if (unit .scopeType != CompilationScope .AsyncFunction && unit .scopeType != CompilationScope .Comprehension ) {
754
- errorCallback .onError (ErrorCallback .ErrorType .Syntax , unit .currentLocation , "'await' outside function" );
768
+ errorCallback .onError (ErrorCallback .ErrorType .Syntax , unit .currentLocation , "'await' outside async function" );
755
769
}
756
770
try {
757
771
node .value .accept (this );
@@ -1336,14 +1350,13 @@ public Void visit(ExprTy.Slice node) {
1336
1350
1337
1351
@ Override
1338
1352
public Void visit (ExprTy .Starred node ) {
1339
- SourceRange savedLocation = setLocation (node );
1340
- try {
1341
- // TODO context?
1342
- node .value .accept (this );
1343
- return null ;
1344
- } finally {
1345
- setLocation (savedLocation );
1353
+ // Valid occurrences are handled by other visitors
1354
+ if (node .context == ExprContext .Store ) {
1355
+ errorCallback .onError (ErrorCallback .ErrorType .Syntax , unit .currentLocation , "starred assignment target must be in a list or tuple" );
1356
+ } else {
1357
+ errorCallback .onError (ErrorCallback .ErrorType .Syntax , unit .currentLocation , "can't use starred expression here" );
1346
1358
}
1359
+ return null ;
1347
1360
}
1348
1361
1349
1362
@ Override
@@ -1436,6 +1449,9 @@ public Void visit(ExprTy.UnaryOp node) {
1436
1449
public Void visit (ExprTy .Yield node ) {
1437
1450
SourceRange savedLocation = setLocation (node );
1438
1451
try {
1452
+ if (!unit .scope .isFunction ()) {
1453
+ errorCallback .onError (ErrorCallback .ErrorType .Syntax , unit .currentLocation , "'yield' outside function" );
1454
+ }
1439
1455
if (node .value != null ) {
1440
1456
node .value .accept (this );
1441
1457
} else {
@@ -1453,6 +1469,12 @@ public Void visit(ExprTy.Yield node) {
1453
1469
public Void visit (ExprTy .YieldFrom node ) {
1454
1470
SourceRange savedLocation = setLocation (node );
1455
1471
try {
1472
+ if (!unit .scope .isFunction ()) {
1473
+ errorCallback .onError (ErrorCallback .ErrorType .Syntax , unit .currentLocation , "'yield' outside function" );
1474
+ }
1475
+ if (unit .scopeType == CompilationScope .AsyncFunction ) {
1476
+ errorCallback .onError (ErrorCallback .ErrorType .Syntax , unit .currentLocation , "'yield from' inside async function" );
1477
+ }
1456
1478
node .value .accept (this );
1457
1479
// TODO GET_YIELD_FROM_ITER
1458
1480
addOp (GET_ITER );
@@ -1966,6 +1988,12 @@ public Void visit(StmtTy.Raise node) {
1966
1988
@ Override
1967
1989
public Void visit (StmtTy .Return node ) {
1968
1990
setLocation (node );
1991
+ if (!unit .scope .isFunction ()) {
1992
+ errorCallback .onError (ErrorCallback .ErrorType .Syntax , unit .currentLocation , "'return' outside function" );
1993
+ }
1994
+ if (node .value != null && unit .scope .isGenerator () && unit .scope .isCoroutine ()) {
1995
+ errorCallback .onError (ErrorCallback .ErrorType .Syntax , unit .currentLocation , "'return' with value in async generator" );
1996
+ }
1969
1997
if (node .value == null ) {
1970
1998
unwindBlockStack (UnwindType .RETURN_CONST );
1971
1999
addOp (LOAD_NONE );
@@ -2042,8 +2070,10 @@ public Void visit(StmtTy.Try node) {
2042
2070
*/
2043
2071
commonCleanupHandler .unwindOffset = -1 ;
2044
2072
for (int i = 0 ; i < node .handlers .length ; i ++) {
2045
- assert !hasBareExcept ;
2046
2073
setLocation (node .handlers [i ]);
2074
+ if (hasBareExcept ) {
2075
+ errorCallback .onError (ErrorCallback .ErrorType .Syntax , unit .currentLocation , "default 'except:' must be last" );
2076
+ }
2047
2077
unit .useNextBlock (nextHandler );
2048
2078
2049
2079
if (i < node .handlers .length - 1 ) {
0 commit comments