11package dev .ultreon .pythonc ;
22
3+ import org .jetbrains .annotations .NotNull ;
4+ import org .jetbrains .annotations .Nullable ;
35import org .objectweb .asm .MethodVisitor ;
46import org .objectweb .asm .Type ;
57
8+ import java .lang .reflect .Constructor ;
9+ import java .lang .reflect .Field ;
10+ import java .lang .reflect .Method ;
611import java .lang .reflect .Modifier ;
7- import java .util .Objects ;
12+ import java .util .* ;
813
914final class JClass implements JvmClass {
1015 private final String className ;
1116 private final Type asmType ;
1217 private final Class <?> type ;
18+ private String alias ;
19+ private final HashMap <String , JvmField > fields = new HashMap <>();
20+ private final Map <String , List <JvmFunction >> functions = new HashMap <>();
1321
14- JClass (String className ) {
22+ JClass (String className , Class <?> type ) {
1523 this .className = className ;
1624 this .asmType = Type .getObjectType (className .replace ("." , "/" ));
17- try {
18- this .type = Class .forName (className .replace ("/" , "." ), false , getClass ().getClassLoader ());
19- } catch (ClassNotFoundException e ) {
20- throw new CompilerException ("JVM class not found: " + className );
21- }
25+ this .alias = alias ;
26+ this .type = type ;
2227 }
2328
2429 @ Override
@@ -85,8 +90,120 @@ public boolean isEnum() {
8590 }
8691
8792 @ Override
88- public boolean doesInherit (Class <?> type ) {
89- return type .isAssignableFrom (this .type );
93+ public boolean doesInherit (PythonCompiler compiler , Type type ) {
94+ JvmClass jvmClass = PythonCompiler .classCache .get (type );
95+ if (jvmClass instanceof JClass jClass ) {
96+ return jClass .type .isAssignableFrom (this .type );
97+ }
98+ return false ;
99+ }
100+
101+ @ Override
102+ public JvmFunction constructor (PythonCompiler compiler , Type [] paramTypes ) {
103+ Method method ;
104+ Constructor <?>[] constructors = type .getConstructors ();
105+ JvmClass [] ourParamTypes = new JvmClass [paramTypes .length ];
106+ for (int i = 0 , paramTypesLength = paramTypes .length ; i < paramTypesLength ; i ++) {
107+ Type paramType = paramTypes [i ];
108+ if (!(PythonCompiler .classCache .load (compiler , paramType )))
109+ throw new CompilerException ("Class '" + paramType .getClassName () + "' not found (" + compiler .getLocation (this ) + ")" );
110+ ourParamTypes [i ] = PythonCompiler .classCache .get (paramType );
111+ }
112+
113+ Constructor <?> theConstructor ;
114+ methodLoop :
115+ for (Constructor <?> constructor1 : constructors ) {
116+ @ NotNull Class <?>[] parameterTypes = constructor1 .getParameterTypes ();
117+ for (int i = 0 , parameterTypesLength = parameterTypes .length ; i < parameterTypesLength ; i ++) {
118+ Class <?> theParamType = parameterTypes [i ];
119+ if (!(PythonCompiler .classCache .load (compiler , Type .getType (theParamType ))))
120+ throw new CompilerException ("Class '" + theParamType .getName () + "' not found (" + compiler .getLocation (this ) + ")" );
121+
122+ if (i > ourParamTypes .length - 1 ) {
123+ continue methodLoop ;
124+ }
125+ if (!ourParamTypes [i ].doesInherit (compiler , Type .getType (theParamType ))) {
126+ continue methodLoop ;
127+ }
128+ }
129+
130+ if (ourParamTypes .length != parameterTypes .length ) {
131+ continue ;
132+ }
133+
134+ JConstructor jFunction = new JConstructor ("__init__" , constructor1 , 0 , 0 );
135+ this .functions .computeIfAbsent ("__init__" , k -> new ArrayList <>()).add (jFunction );
136+ return jFunction ;
137+ }
138+
139+ throw new CompilerException ("Constructor not found (" + compiler .getLocation (this ) + ")" );
140+ }
141+
142+ @ Override
143+ public @ Nullable JvmFunction function (PythonCompiler compiler , String name , Type [] paramTypes ) {
144+ Method method ;
145+ Method [] methodsByName = ClassUtils .getMethodsByName (type , name );
146+ JvmClass [] ourParamTypes = new JvmClass [paramTypes .length ];
147+ for (int i = 0 , paramTypesLength = paramTypes .length ; i < paramTypesLength ; i ++) {
148+ Type paramType = paramTypes [i ];
149+ if (!(PythonCompiler .classCache .load (compiler , paramType )))
150+ throw new CompilerException ("Class '" + paramType .getClassName () + "' not found (" + compiler .getLocation (this ) + ")" );
151+ ourParamTypes [i ] = PythonCompiler .classCache .get (paramType );
152+ }
153+
154+ Method theMethod ;
155+ methodLoop :
156+ for (Method method1 : methodsByName ) {
157+ @ NotNull Class <?>[] parameterTypes = method1 .getParameterTypes ();
158+ for (int i = 0 , parameterTypesLength = parameterTypes .length ; i < parameterTypesLength ; i ++) {
159+ Class <?> theParamType = parameterTypes [i ];
160+ if (!(PythonCompiler .classCache .load (compiler , Type .getType (theParamType ))))
161+ throw new CompilerException ("Class '" + theParamType .getName () + "' not found (" + compiler .getLocation (this ) + ")" );
162+
163+ if (!ourParamTypes [i ].doesInherit (compiler , Type .getType (theParamType ))) {
164+ continue methodLoop ;
165+ }
166+ }
167+
168+ JFunction jFunction = new JFunction (name , method1 , 0 , 0 );
169+ this .functions .computeIfAbsent (name , k -> new ArrayList <>()).add (jFunction );
170+ return jFunction ;
171+ }
172+
173+ throw new CompilerException ("Method '" + name + "' not found (" + compiler .getLocation (this ) + ")" );
174+ }
175+
176+ @ Override
177+ public boolean isPrimitive () {
178+ return type .isPrimitive ();
179+ }
180+
181+ @ Override
182+ public @ Nullable JvmField field (PythonCompiler compiler , String name ) {
183+ Field field ;
184+ try {
185+ field = this .type .getField (name );
186+ } catch (NoSuchFieldException e ) {
187+ return null ;
188+ }
189+ Class <?> type1 = field .getType ();
190+ if (Modifier .isStatic (field .getModifiers ())) {
191+ if (type1 .isPrimitive ()) {
192+ Type asmType = Type .getType (type1 );
193+ Field finalField = field ;
194+ return fields .computeIfAbsent (name , k -> new JField (this , finalField , name , asmType ));
195+ }
196+ Field finalField = field ;
197+ return fields .computeIfAbsent (name , k -> new JField (this , finalField , name , Type .getType (type1 )));
198+ }
199+ if (type1 .isPrimitive ()) {
200+ Type asmType = Type .getType (type1 );
201+ Field finalField1 = field ;
202+ return fields .computeIfAbsent (name , k -> new JField (this , finalField1 , name , asmType ));
203+ } else {
204+ Field finalField2 = field ;
205+ return fields .computeIfAbsent (name , k -> new JField (this , finalField2 , name , Type .getType (type1 )));
206+ }
90207 }
91208
92209 public String className () {
@@ -109,7 +226,7 @@ public int hashCode() {
109226 @ Override
110227 public String toString () {
111228 return "JClass[" +
112- "className=" + className + ']' ;
229+ "className=" + className + ']' ;
113230 }
114231
115232}
0 commit comments