@@ -678,7 +678,9 @@ else if (name.getText().startsWith("_"))
678
678
679
679
writer .returnVoid ();
680
680
writer .end ();
681
-
681
+ } catch (Exception e ) {
682
+ e .printStackTrace ();
683
+ throw new RuntimeException (e );
682
684
} finally {
683
685
flags .clear (F_CPL_STATIC_FUNC );
684
686
flags .clear (F_CPL_CLASS_FUNC );
@@ -1193,7 +1195,7 @@ public Object visitAssignment(PythonParser.AssignmentContext ctx) {
1193
1195
pyVariable .set (mv , this , expr );
1194
1196
}
1195
1197
} else {
1196
- createVariable ( name , switch (visit1 ) {
1198
+ Type type = switch (visit1 ) {
1197
1199
case FuncCall funcCall -> funcCall .type (this );
1198
1200
case Symbol symbol -> symbol .type (this );
1199
1201
case Boolean booleanValue -> Type .BOOLEAN_TYPE ;
@@ -1208,7 +1210,9 @@ public Object visitAssignment(PythonParser.AssignmentContext ctx) {
1208
1210
case PyConstant pyConstant -> pyConstant .type (this );
1209
1211
case PyExpr pyExpr -> pyExpr .type (this );
1210
1212
default -> throw new RuntimeException ("Expression for variable assignment wasn't found." );
1211
- }, switch (visit1 ) {
1213
+ };
1214
+ String s = importType (type );
1215
+ createVariable (name , type , switch (visit1 ) {
1212
1216
case PyConstant pyConstant -> pyConstant ;
1213
1217
case Symbol symbol -> symbol ;
1214
1218
case String string -> new PyConstant (string , ctx .start .getLine ());
@@ -1223,6 +1227,8 @@ public Object visitAssignment(PythonParser.AssignmentContext ctx) {
1223
1227
case PyExpr pyExpr -> pyExpr ;
1224
1228
default -> throw new RuntimeException ("Expression for variable assignment wasn't found." );
1225
1229
}, false );
1230
+
1231
+ imports .remove (s );
1226
1232
}
1227
1233
1228
1234
return Unit .Instance ;
@@ -1295,6 +1301,35 @@ public Object visitAssignment(PythonParser.AssignmentContext ctx) {
1295
1301
}
1296
1302
}
1297
1303
1304
+ private String importType (Type type ) {
1305
+ if (type == null ) throw new RuntimeException ("Can't import null type" );
1306
+ if (type .getSort () == Type .ARRAY ) {
1307
+ importType (type .getElementType ());
1308
+ return null ;
1309
+ }
1310
+ if (type .getSort () != Type .OBJECT ) return null ;
1311
+ Class clazz = null ;
1312
+ try {
1313
+ clazz = Class .forName (type .getClassName (), false , getClass ().getClassLoader ());
1314
+ JClass value = new JClass (type .getClassName ());
1315
+ String internalName = type .getInternalName ();
1316
+ String [] split = internalName .split ("/" );
1317
+ String importedName = split [split .length - 1 ];
1318
+ imports .put (importedName , value );
1319
+ symbols .put (importedName , value );
1320
+ return importedName ;
1321
+ } catch (ClassNotFoundException e ) {
1322
+ PyClass value = classes .get (type .getClassName ());
1323
+ if (value == null ) throw new CompilerException ("JVM Class not found: " + type .getClassName ());
1324
+ String internalName = type .getInternalName ();
1325
+ String [] split = internalName .split ("/" );
1326
+ String importedName = split [split .length - 1 ];
1327
+ imports .put (importedName , value );
1328
+ symbols .put (importedName , value );
1329
+ return importedName ;
1330
+ }
1331
+ }
1332
+
1298
1333
public void loadConstant (ParserRuleContext ctx , Object visit1 , MethodVisitor mv ) {
1299
1334
var a = constant (ctx , visit1 );
1300
1335
@@ -1359,6 +1394,15 @@ public Object visitBitwise_or(PythonParser.Bitwise_orContext ctx) {
1359
1394
}
1360
1395
Object finalValue = value ;
1361
1396
Object finalAddition = addition ;
1397
+ if (flags .get (F_CPL_TYPE_ANNO )) {
1398
+ if (addition != null ) {
1399
+ throw new RuntimeException ("Binary operator is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1400
+ }
1401
+
1402
+ if (value != null ) {
1403
+ return value ;
1404
+ }
1405
+ }
1362
1406
PyEval .Operator operator = null ;
1363
1407
if (ctx .VBAR () != null ) {
1364
1408
operator = PyEval .Operator .OR ;
@@ -1381,6 +1425,15 @@ public Object visitBitwise_xor(PythonParser.Bitwise_xorContext ctx) {
1381
1425
Object finalValue = value ;
1382
1426
Object finalAddition = addition ;
1383
1427
PyEval .Operator operator = null ;
1428
+ if (flags .get (F_CPL_TYPE_ANNO )) {
1429
+ if (addition != null ) {
1430
+ throw new RuntimeException ("Binary operator is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1431
+ }
1432
+
1433
+ if (value != null ) {
1434
+ return value ;
1435
+ }
1436
+ }
1384
1437
if (ctx .CIRCUMFLEX () != null ) {
1385
1438
operator = PyEval .Operator .XOR ;
1386
1439
}
@@ -1440,6 +1493,15 @@ public Object visitComparison(PythonParser.ComparisonContext ctx) {
1440
1493
List <PythonParser .Compare_op_bitwise_or_pairContext > compareOpBitwiseOrPairContexts = ctx .compare_op_bitwise_or_pair ();
1441
1494
if (bitwiseOrContext != null ) {
1442
1495
Object visit = visit (bitwiseOrContext );
1496
+ if (flags .get (F_CPL_TYPE_ANNO )) {
1497
+ if (!compareOpBitwiseOrPairContexts .isEmpty ()) {
1498
+ throw new RuntimeException ("Comparison is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1499
+ }
1500
+
1501
+ if (visit != null ) {
1502
+ return visit ;
1503
+ }
1504
+ }
1443
1505
if (!compareOpBitwiseOrPairContexts .isEmpty ()) {
1444
1506
for (PythonParser .Compare_op_bitwise_or_pairContext compareOpBitwiseOrPairContext : compareOpBitwiseOrPairContexts ) {
1445
1507
Object visit1 = visit (compareOpBitwiseOrPairContext );
@@ -1480,6 +1542,28 @@ public Type type(PythonCompiler compiler) {
1480
1542
@ Override
1481
1543
public Object visitCompare_op_bitwise_or_pair (PythonParser .Compare_op_bitwise_or_pairContext ctx ) {
1482
1544
PythonParser .Eq_bitwise_orContext eqBitwiseOrContext = ctx .eq_bitwise_or ();
1545
+ if (flags .get (F_CPL_TYPE_ANNO )) {
1546
+ if (ctx .eq_bitwise_or () != null ) {
1547
+ throw new RuntimeException ("Equality is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1548
+ }
1549
+ if (ctx .noteq_bitwise_or () != null ) {
1550
+ throw new RuntimeException ("Inequality is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1551
+ }
1552
+ if (ctx .gt_bitwise_or () != null ) {
1553
+ throw new RuntimeException ("Relational operator is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1554
+ }
1555
+ if (ctx .gte_bitwise_or () != null ) {
1556
+ throw new RuntimeException ("Relational operator is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1557
+ }
1558
+ if (ctx .lt_bitwise_or () != null ) {
1559
+ throw new RuntimeException ("Relational operator is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1560
+ }
1561
+ if (ctx .lte_bitwise_or () != null ) {
1562
+ throw new RuntimeException ("Relational operator is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1563
+ }
1564
+
1565
+ throw new RuntimeException ("No supported matching compare_op_bitwise_or_pair found for:\n " + ctx .getText ());
1566
+ }
1483
1567
if (eqBitwiseOrContext != null ) {
1484
1568
return new PyComparison (eqBitwiseOrContext , PyComparison .Comparison .EQ , ctx );
1485
1569
}
@@ -1529,6 +1613,15 @@ public Object visitBitwise_and(PythonParser.Bitwise_andContext ctx) {
1529
1613
Object finalValue = value ;
1530
1614
Object finalAddition = addition ;
1531
1615
PyEval .Operator operator = null ;
1616
+ if (flags .get (F_CPL_TYPE_ANNO )) {
1617
+ if (addition != null ) {
1618
+ throw new RuntimeException ("Type annotation is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1619
+ }
1620
+
1621
+ if (value != null ) {
1622
+ return value ;
1623
+ }
1624
+ }
1532
1625
if (ctx .AMPER () != null ) {
1533
1626
operator = PyEval .Operator .AND ;
1534
1627
}
@@ -1550,6 +1643,15 @@ public Object visitShift_expr(PythonParser.Shift_exprContext ctx) {
1550
1643
Object finalValue = value ;
1551
1644
Object finalAddition = addition ;
1552
1645
PyEval .Operator operator = null ;
1646
+ if (flags .get (F_CPL_TYPE_ANNO )) {
1647
+ if (addition != null ) {
1648
+ throw new RuntimeException ("Type annotation is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1649
+ }
1650
+
1651
+ if (value != null ) {
1652
+ return value ;
1653
+ }
1654
+ }
1553
1655
if (ctx .LEFTSHIFT () != null ) {
1554
1656
operator = PyEval .Operator .LSHIFT ;
1555
1657
} else if (ctx .RIGHTSHIFT () != null ) {
@@ -1573,6 +1675,15 @@ public Object visitSum(PythonParser.SumContext ctx) {
1573
1675
Object finalValue = value ;
1574
1676
Object finalAddition = addition ;
1575
1677
PyEval .Operator operator = null ;
1678
+ if (flags .get (F_CPL_TYPE_ANNO )) {
1679
+ if (addition != null ) {
1680
+ throw new RuntimeException ("Type annotation is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1681
+ }
1682
+
1683
+ if (value != null ) {
1684
+ return value ;
1685
+ }
1686
+ }
1576
1687
if (ctx .PLUS () != null ) {
1577
1688
operator = PyEval .Operator .ADD ;
1578
1689
} else if (ctx .MINUS () != null ) {
@@ -1615,6 +1726,15 @@ public Object visitTerm(PythonParser.TermContext ctx) {
1615
1726
Object finalValue = value ;
1616
1727
Object finalAddition = addition ;
1617
1728
PyEval .Operator operator = null ;
1729
+ if (flags .get (F_CPL_TYPE_ANNO )) {
1730
+ if (addition != null ) {
1731
+ throw new RuntimeException ("Type annotation is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1732
+ }
1733
+
1734
+ if (value != null ) {
1735
+ return value ;
1736
+ }
1737
+ }
1618
1738
if (ctx .STAR () != null ) {
1619
1739
operator = PyEval .Operator .MUL ;
1620
1740
} else if (ctx .SLASH () != null ) {
@@ -1641,6 +1761,9 @@ public Object visitFactor(PythonParser.FactorContext ctx) {
1641
1761
}
1642
1762
Object finalValue = value ;
1643
1763
PyEval .Operator operator = PyEval .Operator .UNARY_MINUS ;
1764
+ if (flags .get (F_CPL_TYPE_ANNO )) {
1765
+ throw new RuntimeException ("Unary operator is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1766
+ }
1644
1767
return new PyEval (this , ctx , operator , finalValue , null );
1645
1768
}
1646
1769
@@ -1655,6 +1778,9 @@ public Object visitFactor(PythonParser.FactorContext ctx) {
1655
1778
}
1656
1779
Object finalValue = value ;
1657
1780
PyEval .Operator operator = PyEval .Operator .UNARY_PLUS ;
1781
+ if (flags .get (F_CPL_TYPE_ANNO )) {
1782
+ throw new RuntimeException ("Unary operator is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1783
+ }
1658
1784
return new PyEval (this , ctx , operator , finalValue , null );
1659
1785
}
1660
1786
@@ -1669,6 +1795,9 @@ public Object visitFactor(PythonParser.FactorContext ctx) {
1669
1795
}
1670
1796
Object finalValue = value ;
1671
1797
PyEval .Operator operator = PyEval .Operator .UNARY_NOT ;
1798
+ if (flags .get (F_CPL_TYPE_ANNO )) {
1799
+ throw new RuntimeException ("Unary operator is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1800
+ }
1672
1801
return new PyEval (this , ctx , operator , finalValue , null );
1673
1802
}
1674
1803
PythonParser .PowerContext powerContext = ctx .power ();
@@ -1694,6 +1823,15 @@ public Object visitPower(PythonParser.PowerContext ctx) {
1694
1823
Object finalValue = value ;
1695
1824
Object finalAddition = addition ;
1696
1825
PyEval .Operator operator = PyEval .Operator .POW ;
1826
+ if (flags .get (F_CPL_TYPE_ANNO )) {
1827
+ if (addition != null ) {
1828
+ throw new RuntimeException ("Type annotation is not allowed in type annotations (at " + fileName + ":" + ctx .getStart ().getLine () + ":" + ctx .getStart ().getCharPositionInLine () + ")" );
1829
+ }
1830
+
1831
+ if (value != null ) {
1832
+ return value ;
1833
+ }
1834
+ }
1697
1835
return new PyEval (this , ctx , operator , finalValue , finalAddition );
1698
1836
1699
1837
}
@@ -2126,12 +2264,7 @@ int createVariable(String name, Type type, PyExpr expr, boolean boxed) {
2126
2264
writer .localVariable (name , Type .getType (Object .class ).getDescriptor (), null , endLabel , endLabel , currentVariableIndex );
2127
2265
mv .visitLineNumber (expr .lineNo (), label );
2128
2266
int opcode ;
2129
- if (!type .equals (Type .getType (String .class )) && !type .equals (Type .LONG_TYPE ) && !type .equals (Type .DOUBLE_TYPE )
2130
- && !type .equals (Type .FLOAT_TYPE ) && !type .equals (Type .INT_TYPE ) && !type .equals (Type .BOOLEAN_TYPE )
2131
- && !type .equals (Type .BYTE_TYPE ) && !type .equals (Type .SHORT_TYPE )
2132
- && symbols .get (type .getClassName ().substring (type .getClassName ().lastIndexOf ('.' ) + 1 )) == null ) {
2133
- throw typeNotFound (type .getClassName (), expr );
2134
- }
2267
+ typeCheck (type , expr );
2135
2268
Context context = writer .getContext ();
2136
2269
context .pop ();
2137
2270
@@ -2142,6 +2275,31 @@ int createVariable(String name, Type type, PyExpr expr, boolean boxed) {
2142
2275
return currentVariableIndex ++;
2143
2276
}
2144
2277
2278
+ public Type typeCheck (Type type , PyExpr expr ) {
2279
+ if (!type .equals (Type .getType (String .class )) && !type .equals (Type .LONG_TYPE ) && !type .equals (Type .DOUBLE_TYPE )
2280
+ && !type .equals (Type .FLOAT_TYPE ) && !type .equals (Type .INT_TYPE ) && !type .equals (Type .BOOLEAN_TYPE )
2281
+ && !type .equals (Type .BYTE_TYPE ) && !type .equals (Type .SHORT_TYPE )
2282
+ && symbols .get (type .getClassName ().substring (type .getClassName ().lastIndexOf ('.' ) + 1 )) == null ) {
2283
+ if (type .getSort () == Type .ARRAY ) {
2284
+ Type actualType = type .getElementType ();
2285
+ while (actualType .getSort () == Type .ARRAY ) {
2286
+ actualType = actualType .getElementType ();
2287
+ }
2288
+ if (!actualType .equals (Type .getType (String .class )) && !actualType .equals (Type .LONG_TYPE ) && !actualType .equals (Type .DOUBLE_TYPE )
2289
+ && !actualType .equals (Type .FLOAT_TYPE ) && !actualType .equals (Type .INT_TYPE ) && !actualType .equals (Type .BOOLEAN_TYPE )
2290
+ && !actualType .equals (Type .BYTE_TYPE ) && !actualType .equals (Type .SHORT_TYPE )
2291
+ && symbols .get (actualType .getClassName ().substring (actualType .getClassName ().lastIndexOf ('.' ) + 1 )) == null ) {
2292
+ throw typeNotFound (actualType .getClassName (), expr );
2293
+ }
2294
+
2295
+ return actualType ;
2296
+ } else {
2297
+ throw typeNotFound (type .getClassName (), expr );
2298
+ }
2299
+ }
2300
+ return type ;
2301
+ }
2302
+
2145
2303
CompilerException typeNotFound (String type , PyExpr expr ) {
2146
2304
return new CompilerException ("Type '" + type + "' not found " + getLocation (expr ));
2147
2305
}
0 commit comments