MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / FindClass

Method FindClass

source/script.cpp:6531–6578  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

6529
6530
6531Object *Script::FindClass(LPCTSTR aClassName, size_t aClassNameLength)
6532{
6533 if (!aClassNameLength)
6534 aClassNameLength = _tcslen(aClassName);
6535 if (!aClassNameLength || aClassNameLength > MAX_CLASS_NAME_LENGTH)
6536 return NULL;
6537
6538 LPTSTR cp, key;
6539 ExprTokenType token;
6540 Object *base_object = NULL;
6541 TCHAR class_name[MAX_CLASS_NAME_LENGTH + 2]; // Extra +1 for '.' to simplify parsing.
6542
6543 // Make temporary copy which we can modify.
6544 tmemcpy(class_name, aClassName, aClassNameLength);
6545 class_name[aClassNameLength] = '.'; // To simplify parsing.
6546 class_name[aClassNameLength + 1] = '\0';
6547
6548 // Get base variable; e.g. "MyClass" in "MyClass.MySubClass".
6549 cp = _tcschr(class_name + 1, '.');
6550 // To reserve for possible future use with local classes, resolve the class variable according
6551 // to the current scope (which is always global for class..extends, but often local for Catch).
6552 // This also avoids confusion due to inconsistency between `catch x` and other references to x.
6553 Var *base_var = FindVar(class_name, cp - class_name);
6554 if (!base_var)
6555 return NULL;
6556
6557 // Although at load time only the "Object" type can exist, dynamic_cast is used in case we're called at run-time:
6558 if ( !(base_var->IsObject() && (base_object = dynamic_cast<Object *>(base_var->Object()))
6559 && base_object->IsDerivedFrom(Object::sClassPrototype)) ) // Rule out something silly like "class x extends MsgBox".
6560 return NULL;
6561
6562 // Even if the loop below has no iterations, it initializes 'key' to the appropriate value:
6563 for (key = cp + 1; cp = _tcschr(key, '.'); key = cp + 1) // For each key in something like TypeVar.Key1.Key2.
6564 {
6565 if (cp == key)
6566 return NULL; // ScriptError(_T("Missing name."), cp);
6567 *cp = '\0'; // Terminate at the delimiting dot.
6568 // Invoking at this stage isn't safe since aClassName could include the name of a
6569 // user-defined property getter, or the class might implement __Get, and the script
6570 // isn't necessarily ready to execute. Get it this way instead:
6571 auto getter = dynamic_cast<BuiltInFunc*>(base_object->GetOwnPropGetter(key));
6572 if (!getter || getter->mBIF != Class_GetNestedClass)
6573 return NULL;
6574 base_object = ((NestedClassInfo*)getter->mData)->class_object;
6575 }
6576
6577 return base_object;
6578}
6579
6580
6581Object *Object::GetUnresolvedClass(LPTSTR &aName)

Callers

nothing calls this directly

Calls 4

IsObjectMethod · 0.80
IsDerivedFromMethod · 0.80
GetOwnPropGetterMethod · 0.80
ObjectMethod · 0.45

Tested by

no test coverage detected