|
1 | 1 | /* |
2 | | - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. |
| 2 | + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. |
3 | 3 | * Copyright (c) 2014, Regents of the University of California |
4 | 4 | * |
5 | 5 | * All rights reserved. |
|
45 | 45 | import static com.oracle.graal.python.nodes.SpecialMethodNames.MRO; |
46 | 46 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__ALLOC__; |
47 | 47 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__CALL__; |
| 48 | +import static com.oracle.graal.python.nodes.SpecialMethodNames.__DIR__; |
48 | 49 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__GETATTRIBUTE__; |
49 | 50 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__GET__; |
50 | 51 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__INIT__; |
|
54 | 55 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__SETATTR__; |
55 | 56 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__SUBCLASSCHECK__; |
56 | 57 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__SUBCLASSES__; |
| 58 | +import static com.oracle.graal.python.nodes.SpecialMethodNames.__SUBCLASSHOOK__; |
57 | 59 | import static com.oracle.graal.python.runtime.exception.PythonErrorType.AttributeError; |
58 | 60 | import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; |
59 | 61 |
|
|
69 | 71 | import com.oracle.graal.python.builtins.PythonBuiltinClassType; |
70 | 72 | import com.oracle.graal.python.builtins.PythonBuiltins; |
71 | 73 | import com.oracle.graal.python.builtins.objects.PNone; |
| 74 | +import com.oracle.graal.python.builtins.objects.PNotImplemented; |
72 | 75 | import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; |
73 | 76 | import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass; |
74 | 77 | import com.oracle.graal.python.builtins.objects.cext.PythonNativeObject; |
|
77 | 80 | import com.oracle.graal.python.builtins.objects.cext.capi.NativeMember; |
78 | 81 | import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage; |
79 | 82 | import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetObjectArrayNode; |
| 83 | +import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ToArrayNode; |
80 | 84 | import com.oracle.graal.python.builtins.objects.dict.PDict; |
81 | 85 | import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; |
82 | 86 | import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; |
|
87 | 91 | import com.oracle.graal.python.builtins.objects.object.ObjectNodes; |
88 | 92 | import com.oracle.graal.python.builtins.objects.object.ObjectNodes.AbstractSetattrNode; |
89 | 93 | import com.oracle.graal.python.builtins.objects.object.PythonObject; |
| 94 | +import com.oracle.graal.python.builtins.objects.set.PSet; |
90 | 95 | import com.oracle.graal.python.builtins.objects.tuple.PTuple; |
91 | 96 | import com.oracle.graal.python.builtins.objects.type.TypeBuiltinsFactory.CallNodeFactory; |
92 | 97 | import com.oracle.graal.python.builtins.objects.type.TypeNodes.CheckCompatibleForAssigmentNode; |
|
100 | 105 | import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; |
101 | 106 | import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.IsSameTypeNodeGen; |
102 | 107 | import com.oracle.graal.python.lib.PyObjectIsTrueNode; |
| 108 | +import com.oracle.graal.python.lib.PyObjectLookupAttr; |
103 | 109 | import com.oracle.graal.python.nodes.BuiltinNames; |
104 | 110 | import com.oracle.graal.python.nodes.ErrorMessages; |
105 | 111 | import com.oracle.graal.python.nodes.PConstructAndRaiseNode; |
@@ -966,6 +972,16 @@ protected boolean isSameType(Object a, Object b) { |
966 | 972 | } |
967 | 973 | } |
968 | 974 |
|
| 975 | + @Builtin(name = __SUBCLASSHOOK__, minNumOfPositionalArgs = 2, isClassmethod = true) |
| 976 | + @GenerateNodeFactory |
| 977 | + abstract static class SubclassHookNode extends PythonBinaryBuiltinNode { |
| 978 | + @SuppressWarnings("unused") |
| 979 | + @Specialization |
| 980 | + Object hook(VirtualFrame frame, Object cls, Object subclass) { |
| 981 | + return PNotImplemented.NOT_IMPLEMENTED; |
| 982 | + } |
| 983 | + } |
| 984 | + |
969 | 985 | @Builtin(name = __SUBCLASSES__, minNumOfPositionalArgs = 1) |
970 | 986 | @GenerateNodeFactory |
971 | 987 | abstract static class SubclassesNode extends PythonUnaryBuiltinNode { |
@@ -1391,4 +1407,45 @@ Object set(Object self, Object value) { |
1391 | 1407 | throw raise(AttributeError, ErrorMessages.CANT_SET_ATTRIBUTES_OF_TYPE_S, GetNameNode.getUncached().execute(self)); |
1392 | 1408 | } |
1393 | 1409 | } |
| 1410 | + |
| 1411 | + @Builtin(name = __DIR__, minNumOfPositionalArgs = 1, doc = "__dir__ for type objects\n\n\tThis includes all attributes of klass and all of the base\n\tclasses recursively.") |
| 1412 | + @GenerateNodeFactory |
| 1413 | + public abstract static class DirNode extends PythonUnaryBuiltinNode { |
| 1414 | + @Specialization |
| 1415 | + Object dir(VirtualFrame frame, Object klass, |
| 1416 | + @Cached PyObjectLookupAttr lookupAttrNode, |
| 1417 | + @Cached com.oracle.graal.python.nodes.call.CallNode callNode, |
| 1418 | + @Cached ToArrayNode toArrayNode, |
| 1419 | + @Cached("createGetAttrNode()") GetFixedAttributeNode getBasesNode, |
| 1420 | + @Cached DirNode dirNode) { |
| 1421 | + PSet names = dir(frame, klass, lookupAttrNode, callNode, getBasesNode, toArrayNode, dirNode); |
| 1422 | + return names; |
| 1423 | + } |
| 1424 | + |
| 1425 | + private PSet dir(VirtualFrame frame, Object klass, PyObjectLookupAttr lookupAttrNode, com.oracle.graal.python.nodes.call.CallNode callNode, GetFixedAttributeNode getBasesNode, |
| 1426 | + ToArrayNode toArrayNode, DirNode dirNode) { |
| 1427 | + PSet names = factory().createSet(); |
| 1428 | + Object updateCallable = lookupAttrNode.execute(frame, names, "update"); |
| 1429 | + Object ns = lookupAttrNode.execute(frame, klass, __DICT__); |
| 1430 | + if (ns != PNone.NO_VALUE) { |
| 1431 | + callNode.execute(frame, updateCallable, ns); |
| 1432 | + } |
| 1433 | + Object basesAttr = getBasesNode.execute(frame, klass); |
| 1434 | + if (basesAttr instanceof PTuple) { |
| 1435 | + Object[] bases = toArrayNode.execute(((PTuple) basesAttr).getSequenceStorage()); |
| 1436 | + for (Object cls : bases) { |
| 1437 | + // Note that since we are only interested in the keys, the order |
| 1438 | + // we merge classes is unimportant |
| 1439 | + Object baseNames = dir(frame, cls, lookupAttrNode, callNode, getBasesNode, toArrayNode, dirNode); |
| 1440 | + callNode.execute(frame, updateCallable, baseNames); |
| 1441 | + } |
| 1442 | + } |
| 1443 | + return names; |
| 1444 | + } |
| 1445 | + |
| 1446 | + protected GetFixedAttributeNode createGetAttrNode() { |
| 1447 | + return GetFixedAttributeNode.create(__BASES__); |
| 1448 | + } |
| 1449 | + } |
| 1450 | + |
1394 | 1451 | } |
0 commit comments