25
25
import com .oracle .graal .python .compiler .OpCodes .CollectionBits ;
26
26
import com .oracle .graal .python .compiler .bytecode_dsl .BytecodeDSLCompiler .BytecodeDSLCompilerContext ;
27
27
import com .oracle .graal .python .compiler .bytecode_dsl .BytecodeDSLCompiler .BytecodeDSLCompilerResult ;
28
- import com .oracle .graal .python .compiler .RaisePythonExceptionErrorCallback ;
29
28
import com .oracle .graal .python .compiler .Unparser ;
30
29
import com .oracle .graal .python .nodes .StringLiterals ;
31
30
import com .oracle .graal .python .nodes .bytecode_dsl .BytecodeDSLCodeUnit ;
32
31
import com .oracle .graal .python .nodes .bytecode_dsl .PBytecodeDSLRootNode ;
33
32
import com .oracle .graal .python .nodes .bytecode_dsl .PBytecodeDSLRootNodeGen ;
34
33
import com .oracle .graal .python .nodes .bytecode_dsl .PBytecodeDSLRootNodeGen .Builder ;
35
- import com .oracle .graal .python .pegparser .ErrorCallback ;
36
34
import com .oracle .graal .python .pegparser .FutureFeature ;
37
35
import com .oracle .graal .python .pegparser .ErrorCallback .ErrorType ;
36
+ import com .oracle .graal .python .pegparser .ErrorCallback .WarningType ;
38
37
import com .oracle .graal .python .pegparser .scope .Scope ;
39
38
import com .oracle .graal .python .pegparser .scope .Scope .DefUse ;
40
39
import com .oracle .graal .python .pegparser .sst .AliasTy ;
57
56
import com .oracle .graal .python .pegparser .sst .StmtTy ;
58
57
import com .oracle .graal .python .pegparser .sst .UnaryOpTy ;
59
58
import com .oracle .graal .python .pegparser .sst .WithItemTy ;
59
+ import com .oracle .graal .python .pegparser .sst .ExprTy .Constant ;
60
60
import com .oracle .graal .python .pegparser .sst .ExprTy .DictComp ;
61
61
import com .oracle .graal .python .pegparser .sst .ExprTy .GeneratorExp ;
62
62
import com .oracle .graal .python .pegparser .sst .ExprTy .Lambda ;
@@ -94,7 +94,6 @@ public class RootNodeCompiler implements BaseBytecodeDSLVisitor<BytecodeDSLCompi
94
94
private final CompilationScope scopeType ;
95
95
private final boolean isInteractive ;
96
96
private final EnumSet <FutureFeature > futureFeatures ;
97
- private final ErrorCallback errorCallback ;
98
97
99
98
// Immutable after construction
100
99
private final HashMap <String , Integer > varnames ;
@@ -120,7 +119,6 @@ public RootNodeCompiler(BytecodeDSLCompilerContext ctx, SSTNode rootNode, EnumSe
120
119
this .scopeType = getScopeType (scope , rootNode );
121
120
this .isInteractive = rootNode instanceof ModTy .Interactive ;
122
121
this .futureFeatures = futureFeatures ;
123
- this .errorCallback = new RaisePythonExceptionErrorCallback (ctx .source , false );
124
122
125
123
this .varnames = new HashMap <>();
126
124
if (scope .isFunction ()) {
@@ -261,7 +259,7 @@ flags, orderedTruffleStringArray(names),
261
259
selfIndex ,
262
260
null ,
263
261
nodes );
264
- rootNode .setMetadata (codeUnit );
262
+ rootNode .setMetadata (codeUnit , ctx . errorCallback );
265
263
return new BytecodeDSLCompilerResult (rootNode , codeUnit );
266
264
}
267
265
@@ -306,12 +304,12 @@ private boolean nonEmpty() {
306
304
protected final void checkForbiddenName (String id , NameOperation context ) {
307
305
if (context == NameOperation .BeginWrite ) {
308
306
if (id .equals ("__debug__" )) {
309
- errorCallback .onError (ErrorType .Syntax , currentLocation , "cannot assign to __debug__" );
307
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "cannot assign to __debug__" );
310
308
}
311
309
}
312
310
if (context == NameOperation .Delete ) {
313
311
if (id .equals ("__debug__" )) {
314
- errorCallback .onError (ErrorType .Syntax , currentLocation , "cannot delete __debug__" );
312
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "cannot delete __debug__" );
315
313
}
316
314
}
317
315
}
@@ -1225,10 +1223,10 @@ public Void visit(ExprTy.Attribute node) {
1225
1223
@ Override
1226
1224
public Void visit (ExprTy .Await node ) {
1227
1225
if (!scope .isFunction ()) {
1228
- errorCallback .onError (ErrorType .Syntax , currentLocation , "'await' outside function" );
1226
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "'await' outside function" );
1229
1227
}
1230
1228
if (scopeType != CompilationScope .AsyncFunction && scopeType != CompilationScope .Comprehension ) {
1231
- errorCallback .onError (ErrorType .Syntax , currentLocation , "'await' outside async function" );
1229
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "'await' outside async function" );
1232
1230
}
1233
1231
1234
1232
beginSourceSection (node , b );
@@ -1365,7 +1363,7 @@ protected final void validateKeywords(KeywordTy[] keywords) {
1365
1363
checkForbiddenName (keywords [i ].arg , NameOperation .BeginWrite );
1366
1364
for (int j = i + 1 ; j < keywords .length ; j ++) {
1367
1365
if (keywords [i ].arg .equals (keywords [j ].arg )) {
1368
- errorCallback .onError (ErrorType .Syntax , currentLocation , "keyword argument repeated: " + keywords [i ].arg );
1366
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "keyword argument repeated: " + keywords [i ].arg );
1369
1367
}
1370
1368
}
1371
1369
}
@@ -1563,6 +1561,7 @@ private void endComparison(CmpOpTy op) {
1563
1561
@ Override
1564
1562
public Void visit (ExprTy .Compare node ) {
1565
1563
beginSourceSection (node , b );
1564
+ checkCompare (node );
1566
1565
1567
1566
boolean multipleComparisons = node .comparators .length > 1 ;
1568
1567
@@ -1600,6 +1599,36 @@ public Void visit(ExprTy.Compare node) {
1600
1599
return null ;
1601
1600
}
1602
1601
1602
+ private void warn (SSTNode node , String message , Object ... arguments ) {
1603
+ ctx .errorCallback .onWarning (WarningType .Syntax , node .getSourceRange (), message , arguments );
1604
+ }
1605
+
1606
+ private void checkCompare (ExprTy node ) {
1607
+ if (!(node instanceof ExprTy .Compare compare )) {
1608
+ return ;
1609
+ }
1610
+ boolean left = checkIsArg (compare .left );
1611
+ int n = compare .ops == null ? 0 : compare .ops .length ;
1612
+ for (int i = 0 ; i < n ; ++i ) {
1613
+ CmpOpTy op = compare .ops [i ];
1614
+ boolean right = checkIsArg (compare .comparators [i ]);
1615
+ if (op == CmpOpTy .Is || op == CmpOpTy .IsNot ) {
1616
+ if (!right || !left ) {
1617
+ warn (compare , op == CmpOpTy .Is ? "\" is\" with a literal. Did you mean \" ==\" ?" : "\" is not\" with a literal. Did you mean \" !=\" ?" );
1618
+ }
1619
+ }
1620
+ left = right ;
1621
+ }
1622
+ }
1623
+
1624
+ private static boolean checkIsArg (ExprTy e ) {
1625
+ if (e instanceof ExprTy .Constant ) {
1626
+ ConstantValue .Kind kind = ((Constant ) e ).value .kind ;
1627
+ return kind == Kind .NONE || kind == Kind .BOOLEAN || kind == Kind .ELLIPSIS ;
1628
+ }
1629
+ return true ;
1630
+ }
1631
+
1603
1632
private void createConstant (ConstantValue value ) {
1604
1633
switch (value .kind ) {
1605
1634
case NONE :
@@ -2331,7 +2360,7 @@ public Void visit(StmtTy.AnnAssign node) {
2331
2360
checkAnnSubscr (subscript .slice );
2332
2361
}
2333
2362
} else {
2334
- errorCallback .onError (ErrorType .Syntax , node .getSourceRange (), "invalid node type for annotated assignment" );
2363
+ ctx . errorCallback .onError (ErrorType .Syntax , node .getSourceRange (), "invalid node type for annotated assignment" );
2335
2364
}
2336
2365
if (!node .isSimple ) {
2337
2366
/*
@@ -2744,10 +2773,10 @@ public Void visit(StmtTy.AsyncFor node) {
2744
2773
@ Override
2745
2774
public Void visit (StmtTy .AsyncWith node ) {
2746
2775
if (!scope .isFunction ()) {
2747
- errorCallback .onError (ErrorType .Syntax , currentLocation , "'async with' outside function" );
2776
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "'async with' outside function" );
2748
2777
}
2749
2778
if (scopeType != CompilationScope .AsyncFunction && scopeType != CompilationScope .Comprehension ) {
2750
- errorCallback .onError (ErrorType .Syntax , currentLocation , "'async with' outside async function" );
2779
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "'async with' outside async function" );
2751
2780
}
2752
2781
beginSourceSection (node , b );
2753
2782
visitWithRecurse (node .items , 0 , node .body , true );
@@ -3230,7 +3259,6 @@ private void visitStatements(StmtTy[] stmts) {
3230
3259
@ Override
3231
3260
public Void visit (StmtTy .If node ) {
3232
3261
beginSourceSection (node , b );
3233
-
3234
3262
if (node .orElse == null || node .orElse .length == 0 ) {
3235
3263
b .beginIfThen ();
3236
3264
visitCondition (node .test );
@@ -3321,7 +3349,7 @@ public Void visit(StmtTy.Import node) {
3321
3349
public Void visit (StmtTy .ImportFrom node ) {
3322
3350
beginSourceSection (node , b );
3323
3351
if (node .getSourceRange ().startLine > ctx .futureLineNumber && "__future__" .equals (node .module )) {
3324
- errorCallback .onError (ErrorType .Syntax , node .getSourceRange (), "from __future__ imports must occur at the beginning of the file" );
3352
+ ctx . errorCallback .onError (ErrorType .Syntax , node .getSourceRange (), "from __future__ imports must occur at the beginning of the file" );
3325
3353
}
3326
3354
3327
3355
TruffleString tsModuleName = toTruffleStringUncached (node .module == null ? "" : node .module );
@@ -3409,7 +3437,7 @@ private BytecodeLocal allocateBindVariable(String name) {
3409
3437
}
3410
3438
3411
3439
private void duplicateStoreError (String name ) {
3412
- errorCallback .onError (ErrorType .Syntax , currentLocation , "multiple assignments to name '%s' in pattern" , name );
3440
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "multiple assignments to name '%s' in pattern" , name );
3413
3441
}
3414
3442
3415
3443
}
@@ -3573,9 +3601,9 @@ private void doVisitPattern(PatternTy.MatchAs node, PatternContext pc) {
3573
3601
// If there's no pattern (e.g., _), it trivially matches. Ensure this is permitted.
3574
3602
if (!pc .allowIrrefutable ) {
3575
3603
if (node .name != null ) {
3576
- errorCallback .onError (ErrorType .Syntax , currentLocation , "name capture '%s' makes remaining patterns unreachable" , node .name );
3604
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "name capture '%s' makes remaining patterns unreachable" , node .name );
3577
3605
}
3578
- errorCallback .onError (ErrorType .Syntax , currentLocation , "wildcard makes remaining patterns unreachable" );
3606
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "wildcard makes remaining patterns unreachable" );
3579
3607
}
3580
3608
b .emitLoadConstant (true );
3581
3609
} else {
@@ -3638,12 +3666,12 @@ private void patternUnpackHelper(PatternTy[] patterns, PatternContext pc) {
3638
3666
PatternTy pattern = patterns [i ];
3639
3667
if (pattern instanceof PatternTy .MatchStar ) {
3640
3668
if (seenStar ) {
3641
- errorCallback .onError (ErrorType .Syntax , currentLocation , "multiple starred expressions in sequence pattern" );
3669
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "multiple starred expressions in sequence pattern" );
3642
3670
}
3643
3671
seenStar = true ;
3644
3672
int countAfter = n - i - 1 ;
3645
3673
if (countAfter != (byte ) countAfter ) {
3646
- errorCallback .onError (ErrorType .Syntax , currentLocation , "too many expressions in star-unpacking sequence pattern" );
3674
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "too many expressions in star-unpacking sequence pattern" );
3647
3675
}
3648
3676
// If there's a star pattern, emit UnpackEx.
3649
3677
b .beginUnpackEx (i , countAfter );
@@ -3724,7 +3752,7 @@ private void doVisitPattern(PatternTy.MatchSequence node, PatternContext pc) {
3724
3752
PatternTy pattern = node .patterns [i ];
3725
3753
if (pattern instanceof PatternTy .MatchStar ) {
3726
3754
if (star >= 0 ) {
3727
- errorCallback .onError (ErrorType .Syntax , node .getSourceRange (), "multiple starred names in sequence pattern" );
3755
+ ctx . errorCallback .onError (ErrorType .Syntax , node .getSourceRange (), "multiple starred names in sequence pattern" );
3728
3756
}
3729
3757
starWildcard = wildcardStarCheck (pattern );
3730
3758
onlyWildcard &= starWildcard ;
@@ -3820,7 +3848,7 @@ private void doVisitPattern(PatternTy.MatchValue node, PatternContext pc) {
3820
3848
} else if (node .value instanceof ExprTy .Constant || node .value instanceof ExprTy .Attribute ) {
3821
3849
node .value .accept (this );
3822
3850
} else {
3823
- errorCallback .onError (ErrorType .Syntax , currentLocation , "patterns may only match literals and attribute lookups" );
3851
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "patterns may only match literals and attribute lookups" );
3824
3852
}
3825
3853
b .endEq ();
3826
3854
}
@@ -3955,7 +3983,7 @@ public Void visit(StmtTy.Raise node) {
3955
3983
@ Override
3956
3984
public Void visit (StmtTy .Return node ) {
3957
3985
if (!scope .isFunction ()) {
3958
- errorCallback .onError (ErrorType .Syntax , currentLocation , "'return' outside function" );
3986
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "'return' outside function" );
3959
3987
}
3960
3988
3961
3989
beginSourceSection (node , b );
@@ -4147,7 +4175,7 @@ private void emitTryExceptElse(StmtTy.Try node) {
4147
4175
for (ExceptHandlerTy h : node .handlers ) {
4148
4176
beginSourceSection (h , b );
4149
4177
if (bareExceptRange != null ) {
4150
- errorCallback .onError (ErrorType .Syntax , currentLocation , "default 'except:' must be last" );
4178
+ ctx . errorCallback .onError (ErrorType .Syntax , currentLocation , "default 'except:' must be last" );
4151
4179
}
4152
4180
4153
4181
ExceptHandlerTy .ExceptHandler handler = (ExceptHandlerTy .ExceptHandler ) h ;
0 commit comments