@@ -678,7 +678,9 @@ else if (name.getText().startsWith("_"))
678678
679679 writer .returnVoid ();
680680 writer .end ();
681-
681+ } catch (Exception e ) {
682+ e .printStackTrace ();
683+ throw new RuntimeException (e );
682684 } finally {
683685 flags .clear (F_CPL_STATIC_FUNC );
684686 flags .clear (F_CPL_CLASS_FUNC );
@@ -1193,7 +1195,7 @@ public Object visitAssignment(PythonParser.AssignmentContext ctx) {
11931195 pyVariable .set (mv , this , expr );
11941196 }
11951197 } else {
1196- createVariable ( name , switch (visit1 ) {
1198+ Type type = switch (visit1 ) {
11971199 case FuncCall funcCall -> funcCall .type (this );
11981200 case Symbol symbol -> symbol .type (this );
11991201 case Boolean booleanValue -> Type .BOOLEAN_TYPE ;
@@ -1208,7 +1210,9 @@ public Object visitAssignment(PythonParser.AssignmentContext ctx) {
12081210 case PyConstant pyConstant -> pyConstant .type (this );
12091211 case PyExpr pyExpr -> pyExpr .type (this );
12101212 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 ) {
12121216 case PyConstant pyConstant -> pyConstant ;
12131217 case Symbol symbol -> symbol ;
12141218 case String string -> new PyConstant (string , ctx .start .getLine ());
@@ -1223,6 +1227,8 @@ public Object visitAssignment(PythonParser.AssignmentContext ctx) {
12231227 case PyExpr pyExpr -> pyExpr ;
12241228 default -> throw new RuntimeException ("Expression for variable assignment wasn't found." );
12251229 }, false );
1230+
1231+ imports .remove (s );
12261232 }
12271233
12281234 return Unit .Instance ;
@@ -1295,6 +1301,35 @@ public Object visitAssignment(PythonParser.AssignmentContext ctx) {
12951301 }
12961302 }
12971303
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+
12981333 public void loadConstant (ParserRuleContext ctx , Object visit1 , MethodVisitor mv ) {
12991334 var a = constant (ctx , visit1 );
13001335
@@ -1359,6 +1394,15 @@ public Object visitBitwise_or(PythonParser.Bitwise_orContext ctx) {
13591394 }
13601395 Object finalValue = value ;
13611396 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+ }
13621406 PyEval .Operator operator = null ;
13631407 if (ctx .VBAR () != null ) {
13641408 operator = PyEval .Operator .OR ;
@@ -1381,6 +1425,15 @@ public Object visitBitwise_xor(PythonParser.Bitwise_xorContext ctx) {
13811425 Object finalValue = value ;
13821426 Object finalAddition = addition ;
13831427 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+ }
13841437 if (ctx .CIRCUMFLEX () != null ) {
13851438 operator = PyEval .Operator .XOR ;
13861439 }
@@ -1440,6 +1493,15 @@ public Object visitComparison(PythonParser.ComparisonContext ctx) {
14401493 List <PythonParser .Compare_op_bitwise_or_pairContext > compareOpBitwiseOrPairContexts = ctx .compare_op_bitwise_or_pair ();
14411494 if (bitwiseOrContext != null ) {
14421495 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+ }
14431505 if (!compareOpBitwiseOrPairContexts .isEmpty ()) {
14441506 for (PythonParser .Compare_op_bitwise_or_pairContext compareOpBitwiseOrPairContext : compareOpBitwiseOrPairContexts ) {
14451507 Object visit1 = visit (compareOpBitwiseOrPairContext );
@@ -1480,6 +1542,28 @@ public Type type(PythonCompiler compiler) {
14801542 @ Override
14811543 public Object visitCompare_op_bitwise_or_pair (PythonParser .Compare_op_bitwise_or_pairContext ctx ) {
14821544 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+ }
14831567 if (eqBitwiseOrContext != null ) {
14841568 return new PyComparison (eqBitwiseOrContext , PyComparison .Comparison .EQ , ctx );
14851569 }
@@ -1529,6 +1613,15 @@ public Object visitBitwise_and(PythonParser.Bitwise_andContext ctx) {
15291613 Object finalValue = value ;
15301614 Object finalAddition = addition ;
15311615 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+ }
15321625 if (ctx .AMPER () != null ) {
15331626 operator = PyEval .Operator .AND ;
15341627 }
@@ -1550,6 +1643,15 @@ public Object visitShift_expr(PythonParser.Shift_exprContext ctx) {
15501643 Object finalValue = value ;
15511644 Object finalAddition = addition ;
15521645 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+ }
15531655 if (ctx .LEFTSHIFT () != null ) {
15541656 operator = PyEval .Operator .LSHIFT ;
15551657 } else if (ctx .RIGHTSHIFT () != null ) {
@@ -1573,6 +1675,15 @@ public Object visitSum(PythonParser.SumContext ctx) {
15731675 Object finalValue = value ;
15741676 Object finalAddition = addition ;
15751677 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+ }
15761687 if (ctx .PLUS () != null ) {
15771688 operator = PyEval .Operator .ADD ;
15781689 } else if (ctx .MINUS () != null ) {
@@ -1615,6 +1726,15 @@ public Object visitTerm(PythonParser.TermContext ctx) {
16151726 Object finalValue = value ;
16161727 Object finalAddition = addition ;
16171728 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+ }
16181738 if (ctx .STAR () != null ) {
16191739 operator = PyEval .Operator .MUL ;
16201740 } else if (ctx .SLASH () != null ) {
@@ -1641,6 +1761,9 @@ public Object visitFactor(PythonParser.FactorContext ctx) {
16411761 }
16421762 Object finalValue = value ;
16431763 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+ }
16441767 return new PyEval (this , ctx , operator , finalValue , null );
16451768 }
16461769
@@ -1655,6 +1778,9 @@ public Object visitFactor(PythonParser.FactorContext ctx) {
16551778 }
16561779 Object finalValue = value ;
16571780 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+ }
16581784 return new PyEval (this , ctx , operator , finalValue , null );
16591785 }
16601786
@@ -1669,6 +1795,9 @@ public Object visitFactor(PythonParser.FactorContext ctx) {
16691795 }
16701796 Object finalValue = value ;
16711797 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+ }
16721801 return new PyEval (this , ctx , operator , finalValue , null );
16731802 }
16741803 PythonParser .PowerContext powerContext = ctx .power ();
@@ -1694,6 +1823,15 @@ public Object visitPower(PythonParser.PowerContext ctx) {
16941823 Object finalValue = value ;
16951824 Object finalAddition = addition ;
16961825 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+ }
16971835 return new PyEval (this , ctx , operator , finalValue , finalAddition );
16981836
16991837 }
@@ -2126,12 +2264,7 @@ int createVariable(String name, Type type, PyExpr expr, boolean boxed) {
21262264 writer .localVariable (name , Type .getType (Object .class ).getDescriptor (), null , endLabel , endLabel , currentVariableIndex );
21272265 mv .visitLineNumber (expr .lineNo (), label );
21282266 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 );
21352268 Context context = writer .getContext ();
21362269 context .pop ();
21372270
@@ -2142,6 +2275,31 @@ int createVariable(String name, Type type, PyExpr expr, boolean boxed) {
21422275 return currentVariableIndex ++;
21432276 }
21442277
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+
21452303 CompilerException typeNotFound (String type , PyExpr expr ) {
21462304 return new CompilerException ("Type '" + type + "' not found " + getLocation (expr ));
21472305 }
0 commit comments