173
173
import com .oracle .graal .python .nodes .function .builtins .clinic .ArgumentClinicProvider ;
174
174
import com .oracle .graal .python .nodes .object .GetClassNode ;
175
175
import com .oracle .graal .python .nodes .object .IsBuiltinClassProfile ;
176
+ import com .oracle .graal .python .nodes .statement .AbstractImportNode ;
176
177
import com .oracle .graal .python .nodes .subscript .SetItemNode ;
177
178
import com .oracle .graal .python .nodes .truffle .PythonArithmeticTypes ;
178
179
import com .oracle .graal .python .nodes .util .CannotCastException ;
197
198
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
198
199
import com .oracle .truffle .api .RootCallTarget ;
199
200
import com .oracle .truffle .api .TruffleLanguage .ContextReference ;
201
+ import com .oracle .truffle .api .TruffleLanguage .Env ;
200
202
import com .oracle .truffle .api .TruffleLanguage .LanguageReference ;
201
203
import com .oracle .truffle .api .debug .Debugger ;
202
204
import com .oracle .truffle .api .dsl .Cached ;
@@ -2051,6 +2053,12 @@ Object calculate(Object metatype, PTuple bases,
2051
2053
@ Builtin (name = BuiltinNames .__BUILD_CLASS__ , minNumOfPositionalArgs = 1 , takesVarArgs = true , takesVarKeywordArgs = true )
2052
2054
@ GenerateNodeFactory
2053
2055
public abstract static class BuildClassNode extends PythonVarargsBuiltinNode {
2056
+ @ TruffleBoundary
2057
+ private static Object buildJavaClass (Object func , String name , Object base ) {
2058
+ Object module = AbstractImportNode .importModule (BuiltinNames .__GRAALPYTHON__ );
2059
+ Object buildFunction = PythonObjectLibrary .getUncached ().lookupAttribute (module , null , "build_java_class" );
2060
+ return CallNode .getUncached ().execute (buildFunction , func , name , base );
2061
+ }
2054
2062
2055
2063
@ Specialization
2056
2064
protected Object doItNonFunction (VirtualFrame frame , Object function , Object [] arguments , PKeyword [] keywords ,
@@ -2067,31 +2075,37 @@ protected Object doItNonFunction(VirtualFrame frame, Object function, Object[] a
2067
2075
@ Cached SetItemNode setOrigBases ,
2068
2076
@ Cached GetClassNode getClass ) {
2069
2077
2078
+ if (arguments .length < 1 ) {
2079
+ throw raise (PythonErrorType .TypeError , "__build_class__: not enough arguments" );
2080
+ }
2081
+
2082
+ if (!PGuards .isFunction (function )) {
2083
+ throw raise (PythonErrorType .TypeError , "__build_class__: func must be a function" );
2084
+ }
2085
+ String name ;
2086
+ try {
2087
+ name = CastToJavaStringNode .getUncached ().execute (arguments [0 ]);
2088
+ } catch (CannotCastException e ) {
2089
+ throw raise (PythonErrorType .TypeError , "__build_class__: name is not a string" );
2090
+ }
2091
+
2092
+ Object [] basesArray = Arrays .copyOfRange (arguments , 1 , arguments .length );
2093
+ PTuple origBases = factory .createTuple (basesArray );
2094
+
2095
+ Env env = PythonLanguage .getContext ().getEnv ();
2096
+ if (arguments .length == 2 && env .isHostObject (arguments [1 ]) && env .asHostObject (arguments [1 ]) instanceof Class <?>) {
2097
+ // we want to subclass a Java class
2098
+ return buildJavaClass (function , name , arguments [1 ]);
2099
+ }
2100
+
2070
2101
class InitializeBuildClass {
2071
- String name ;
2072
2102
boolean isClass ;
2073
2103
Object meta ;
2074
2104
PKeyword [] mkw ;
2075
2105
PTuple bases ;
2076
- PTuple origBases ;
2077
2106
2078
2107
@ TruffleBoundary
2079
2108
InitializeBuildClass () {
2080
- if (arguments .length < 1 ) {
2081
- throw raise (PythonErrorType .TypeError , "__build_class__: not enough arguments" );
2082
- }
2083
-
2084
- if (!PGuards .isFunction (function )) {
2085
- throw raise (PythonErrorType .TypeError , "__build_class__: func must be a function" );
2086
- }
2087
- try {
2088
- name = CastToJavaStringNode .getUncached ().execute (arguments [0 ]);
2089
- } catch (CannotCastException e ) {
2090
- throw raise (PythonErrorType .TypeError , "__build_class__: name is not a string" );
2091
- }
2092
-
2093
- Object [] basesArray = Arrays .copyOfRange (arguments , 1 , arguments .length );
2094
- origBases = factory .createTuple (basesArray );
2095
2109
2096
2110
bases = update .execute (origBases , basesArray , basesArray .length );
2097
2111
@@ -2137,7 +2151,7 @@ class InitializeBuildClass {
2137
2151
if (PGuards .isNoValue (prep )) {
2138
2152
ns = factory .createDict ();
2139
2153
} else {
2140
- Object [] args = PGuards .isFunction (prep ) ? new Object []{init . name , init .bases } : new Object []{init .meta , init . name , init .bases };
2154
+ Object [] args = PGuards .isFunction (prep ) ? new Object []{name , init .bases } : new Object []{init .meta , name , init .bases };
2141
2155
ns = callPrep .execute (frame , prep , args , init .mkw );
2142
2156
}
2143
2157
if (PGuards .isNoValue (getGetItem .execute (getGetItemClass .execute (ns )))) {
@@ -2148,10 +2162,10 @@ class InitializeBuildClass {
2148
2162
}
2149
2163
}
2150
2164
callBody .executeObject (frame , function , ns );
2151
- if (init .bases != init . origBases ) {
2152
- setOrigBases .executeWith (frame , ns , SpecialAttributeNames .__ORIG_BASES__ , init . origBases );
2165
+ if (init .bases != origBases ) {
2166
+ setOrigBases .executeWith (frame , ns , SpecialAttributeNames .__ORIG_BASES__ , origBases );
2153
2167
}
2154
- Object cls = callType .execute (frame , init .meta , new Object []{init . name , init .bases , ns }, init .mkw );
2168
+ Object cls = callType .execute (frame , init .meta , new Object []{name , init .bases , ns }, init .mkw );
2155
2169
2156
2170
/*
2157
2171
* We could check here and throw "__class__ not set defining..." errors.
0 commit comments