PythonObject PythonObject::ResolveName(llvm::StringRef name) const { // Resolve the name in the context of the specified object. If, for example, // `this` refers to a PyModule, then this will look for `name` in this // module. If `this` refers to a PyType, then it will resolve `name` as an // attribute of that type. If `this` refers to an instance of an object, // then it will resolve `name` as the value of the specified field. // // This function handles dotted names so that, for example, if `m_py_obj` // refers to the `sys` module, and `name` == "path.append", then it will find // the function `sys.path.append`. size_t dot_pos = name.find('.'); if (dot_pos == llvm::StringRef::npos) { // No dots in the name, we should be able to find the value immediately as // an attribute of `m_py_obj`. return GetAttributeValue(name); } // Look up the first piece of the name, and resolve the rest as a child of // that. PythonObject parent = ResolveName(name.substr(0, dot_pos)); if (!parent.IsAllocated()) return PythonObject(); // Tail recursion.. should be optimized by the compiler return parent.ResolveName(name.substr(dot_pos + 1)); }
PythonObject PythonObject::ResolveNameWithDictionary(llvm::StringRef name, const PythonDictionary &dict) { size_t dot_pos = name.find('.'); llvm::StringRef piece = name.substr(0, dot_pos); PythonObject result = dict.GetItemForKey(PythonString(piece)); if (dot_pos == llvm::StringRef::npos) { // There was no dot, we're done. return result; } // There was a dot. The remaining portion of the name should be looked up in // the context of the object that was found in the dictionary. return result.ResolveName(name.substr(dot_pos + 1)); }