|
44 | 44 | import static com.oracle.graal.python.nodes.BuiltinNames.J_INTEROP_BEHAVIOR;
|
45 | 45 | import static com.oracle.graal.python.nodes.BuiltinNames.J_REGISTER_INTEROP_BEHAVIOR;
|
46 | 46 | import static com.oracle.graal.python.nodes.BuiltinNames.T_REGISTER_INTEROP_BEHAVIOR;
|
| 47 | +import static com.oracle.graal.python.nodes.BuiltinNames.J_REGISTER_JAVA_INTEROP_TYPE; |
47 | 48 | import static com.oracle.graal.python.nodes.ErrorMessages.ARG_MUST_BE_NUMBER;
|
48 | 49 | import static com.oracle.graal.python.nodes.ErrorMessages.S_ARG_MUST_BE_S_NOT_P;
|
49 | 50 | import static com.oracle.graal.python.nodes.ErrorMessages.S_CANNOT_HAVE_S;
|
|
61 | 62 | import static com.oracle.graal.python.nodes.StringLiterals.T_READABLE;
|
62 | 63 | import static com.oracle.graal.python.nodes.StringLiterals.T_WRITABLE;
|
63 | 64 | import static com.oracle.graal.python.nodes.truffle.TruffleStringMigrationHelpers.isJavaString;
|
| 65 | +import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError; |
64 | 66 | import static com.oracle.graal.python.runtime.exception.PythonErrorType.OSError;
|
65 | 67 | import static com.oracle.graal.python.runtime.exception.PythonErrorType.RuntimeError;
|
66 | 68 | import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
|
@@ -742,6 +744,46 @@ public static PKeyword[] createKwDefaults(Object receiver) {
|
742 | 744 | }
|
743 | 745 | }
|
744 | 746 |
|
| 747 | + @Builtin(name = J_REGISTER_JAVA_INTEROP_TYPE, minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 2, takesVarArgs = true, keywordOnlyNames = "overwrite", doc = """ |
| 748 | + register_java_interop_type(javaClassName, pythonClass, overwrite=None) |
| 749 | + |
| 750 | + Example registering a custom interop type for the Java ArrayList |
| 751 | +
|
| 752 | + >>> from polyglot import register_java_interop_type |
| 753 | +
|
| 754 | + >>> class jArrayList(__graalpython__.ForeignType): |
| 755 | + ... def append(self, element): |
| 756 | + ... self.add(element) |
| 757 | +
|
| 758 | + >>> register_java_interop_type("java.util.ArrayList", jArrayList) |
| 759 | + |
| 760 | + For subsequent registrations with overwrite behavior use |
| 761 | + >>> register_java_interop_type("java.util.ArrayList", newJArrayList, overwrite=True) |
| 762 | + """) |
| 763 | + @GenerateNodeFactory |
| 764 | + public abstract static class RegisterJavaInteropTypeNode extends PythonBuiltinNode { |
| 765 | + |
| 766 | + @Specialization |
| 767 | + @TruffleBoundary |
| 768 | + Object register(TruffleString javaClassName, PythonClass pythonClass, Object overwrite, |
| 769 | + @Bind("this") Node inliningTarget, |
| 770 | + @Cached TypeNodes.IsTypeNode isClassTypeNode, |
| 771 | + @Cached PRaiseNode raiseNode) { |
| 772 | + if (!isClassTypeNode.execute(inliningTarget, pythonClass)) { |
| 773 | + throw raiseNode.raise(ValueError, S_ARG_MUST_BE_S_NOT_P, "second", "a python class", pythonClass); |
| 774 | + } |
| 775 | + // Get registry for custom interop types from PythonContext |
| 776 | + Map<Object, PythonClass> interopTypeRegistry = PythonContext.get(this).getInteropTypeRegistry(); |
| 777 | + String javaClassNameAsString = javaClassName.toString(); |
| 778 | + // Check if already registered and if overwrite is configured |
| 779 | + if (interopTypeRegistry.containsKey(javaClassNameAsString) && !Boolean.TRUE.equals(overwrite)) { |
| 780 | + throw raiseNode.raise(KeyError, INTEROP_TYPE_ALREADY_REGISTERED, javaClassNameAsString); |
| 781 | + } |
| 782 | + interopTypeRegistry.put(javaClassNameAsString, pythonClass); |
| 783 | + return PNone.NONE; |
| 784 | + } |
| 785 | + } |
| 786 | + |
745 | 787 | @Builtin(name = J_REGISTER_INTEROP_BEHAVIOR, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 1, takesVarKeywordArgs = true, keywordOnlyNames = {"is_boolean", "is_date",
|
746 | 788 | "is_duration", "is_iterator", "is_number", "is_string", "is_time", "is_time_zone", "is_executable", "fits_in_big_integer", "fits_in_byte", "fits_in_double", "fits_in_float",
|
747 | 789 | "fits_in_int", "fits_in_long", "fits_in_short", "as_big_integer", "as_boolean", "as_byte", "as_date", "as_double", "as_duration", "as_float", "as_int", "as_long", "as_short",
|
|
0 commit comments