|
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