From 078727c4a71eeb2d9e188d1a4174fd1a6ce48b19 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 10 Oct 2023 13:20:35 -0700 Subject: [PATCH] Hide internal generated methods from reflection, fix ctor/dtor names --- BeefLibs/corlib/src/IRefCounted.bf | 4 ++-- BeefLibs/corlib/src/Reflection/MethodInfo.bf | 25 +++++++++++++++----- BeefLibs/corlib/src/Type.bf | 7 ++++++ IDEHelper/Compiler/BfModule.cpp | 4 +++- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 8 +++++++ IDEHelper/Compiler/BfResolvedTypeUtils.h | 1 + IDEHelper/Compiler/BfSystem.cpp | 18 ++++++++++++++ IDEHelper/Compiler/BfSystem.h | 8 +++++++ IDEHelper/Compiler/CeMachine.cpp | 7 +++--- IDEHelper/Tests/src/Reflection.bf | 6 ++--- 10 files changed, 73 insertions(+), 15 deletions(-) diff --git a/BeefLibs/corlib/src/IRefCounted.bf b/BeefLibs/corlib/src/IRefCounted.bf index a62a01d0..f10b3528 100644 --- a/BeefLibs/corlib/src/IRefCounted.bf +++ b/BeefLibs/corlib/src/IRefCounted.bf @@ -105,7 +105,7 @@ namespace System { String emitStr = scope .(); - for (var methodInfo in typeof(T).GetMethods(.Public)) + for (var methodInfo in typeof(T).GetMethods(.Public | .DeclaredOnly)) { if (methodInfo.IsStatic) continue; @@ -200,7 +200,7 @@ namespace System { String emitStr = scope .(); - for (var methodInfo in typeof(T).GetMethods(.Public)) + for (var methodInfo in typeof(T).GetMethods(.Public | .DeclaredOnly)) { if (methodInfo.IsStatic) continue; diff --git a/BeefLibs/corlib/src/Reflection/MethodInfo.bf b/BeefLibs/corlib/src/Reflection/MethodInfo.bf index b4ec4d38..21a5d34d 100644 --- a/BeefLibs/corlib/src/Reflection/MethodInfo.bf +++ b/BeefLibs/corlib/src/Reflection/MethodInfo.bf @@ -53,6 +53,9 @@ namespace System.Reflection public bool IsStatic => Compiler.IsComptime ? Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mMethodFlags.HasFlag(.Static) : mData.mMethodData.[Friend]mFlags.HasFlag(.Static); + public bool CanReflect => Compiler.IsComptime ? + Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mComptimeMethodFlags.HasFlag(.NoReflect) : + mData.mMethodData.[Friend]mFlags.HasFlag(.SpecialName); public StringView Name => Compiler.IsComptime ? Type.[Friend]Comptime_Method_GetName(mData.mComptimeMethodInstance) : @@ -66,12 +69,12 @@ namespace System.Reflection 0; public bool IsConstructor => Compiler.IsComptime ? - (Name == "__BfCtor" || Name == "__BfStaticCtor") : - (mData.mMethodData.mName === "__BfCtor" || mData.mMethodData.mName === "__BfStaticCtor"); + Name == "this" : + mData.mMethodData.mName === "this"; public bool IsDestructor => Compiler.IsComptime ? - (Name == "__BfDtor" || Name == "__BfStaticDtor") : - (mData.mMethodData.mName === "__BfDtor" || mData.mMethodData.mName === "__BfStaticDtor"); + Name == "~this" : + mData.mMethodData.mName === "~this"; public Type ReturnType => Compiler.IsComptime ? Type.[Friend]GetType((.)Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mReturnTypeId) : @@ -1071,9 +1074,19 @@ namespace System.Reflection mIdx++; int64 nativeMethodHandle = Type.[Friend]Comptime_GetMethod((int32)mTypeInstance.TypeId, mIdx); if (nativeMethodHandle == 0) - return false; - let info = Type.[Friend]Comptime_Method_GetInfo(nativeMethodHandle); + { + if (mBindingFlags.HasFlag(.DeclaredOnly)) + return false; + if (mTypeInstance.[Friend]mBaseType == 0) + return false; + mTypeInstance = Type.[Friend]GetType(mTypeInstance.[Friend]mBaseType) as TypeInstance; + mIdx = -1; + continue; + } + let info = Type.[Friend]Comptime_Method_GetInfo(nativeMethodHandle); + if (info.mComptimeMethodFlags.HasFlag(.NoReflect)) + continue; bool matches = (mBindingFlags.HasFlag(BindingFlags.Static) && (info.mMethodFlags.HasFlag(.Static))); matches |= (mBindingFlags.HasFlag(BindingFlags.Instance) && (!info.mMethodFlags.HasFlag(.Static))); matches |= (mBindingFlags.HasFlag(BindingFlags.Public) && (info.mMethodFlags.HasFlag(.Public))); diff --git a/BeefLibs/corlib/src/Type.bf b/BeefLibs/corlib/src/Type.bf index 02109e92..fc2bb3c6 100644 --- a/BeefLibs/corlib/src/Type.bf +++ b/BeefLibs/corlib/src/Type.bf @@ -514,6 +514,12 @@ namespace System return (int32)mTypeId; } + public enum ComptimeMethodFlags : int8 + { + None, + NoReflect + } + [CRepr, Packed] public struct ComptimeMethodData { @@ -521,6 +527,7 @@ namespace System public int32 mParamCount; public int32 mGenericArgCount; public MethodFlags mMethodFlags; + public ComptimeMethodFlags mComptimeMethodFlags; public int32 mMethodIdx; } diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 3e6890df..aa6c37c0 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -7292,6 +7292,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin continue; if (defaultMethod->mMethodDef->mMethodType == BfMethodType_CtorNoBody) continue; + if (!defaultMethod->mMethodDef->CanReflect()) + continue; auto methodReflectKind = (BfReflectKind)(reflectKind & ~BfReflectKind_User); @@ -7394,7 +7396,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin funcVal = mBfIRBuilder->CreateBitCast(moduleMethodInstance.mFunc, voidPtrIRType); } - BfIRValue methodNameConst = GetStringObjectValue(methodDef->mName, !mIsComptimeModule); + BfIRValue methodNameConst = GetStringObjectValue(methodDef->GetReflectName(), !mIsComptimeModule); BfMethodFlags methodFlags = defaultMethod->GetMethodFlags(); diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index b444d180..5cd30867 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -842,6 +842,14 @@ BfMethodFlags BfMethodInstance::GetMethodFlags() return methodFlags; } +BfComptimeMethodFlags BfMethodInstance::GetComptimeMethodFlags() +{ + BfComptimeMethodFlags methodFlags = (BfComptimeMethodFlags)0; + if (!mMethodDef->CanReflect()) + methodFlags = (BfComptimeMethodFlags)(methodFlags | BfComptimeMethodFlags_NoReflect); + return methodFlags; +} + void BfMethodInstance::UndoDeclaration(bool keepIRFunction) { if (mMethodInfoEx != NULL) diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 473d6b8b..c8dc53ab 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -973,6 +973,7 @@ public: BfImportKind GetImportKind(); BfMethodFlags GetMethodFlags(); + BfComptimeMethodFlags GetComptimeMethodFlags(); void UndoDeclaration(bool keepIRFunction = false); BfTypeInstance* GetOwner(); BfModule* GetModule(); diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index 09ccca04..4a301b1d 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/IDEHelper/Compiler/BfSystem.cpp @@ -648,6 +648,15 @@ String BfMethodDef::ToString() return methodText; } +String BfMethodDef::GetReflectName() +{ + if (mMethodType == BfMethodType_Ctor) + return "this"; + if (mMethodType == BfMethodType_Dtor) + return "~this"; + return mName; +} + int BfMethodDef::GetExplicitParamCount() { for (int i = 0; i < (int)mParams.size(); i++) @@ -675,6 +684,15 @@ void BfMethodDef::BuildParamNameMap() (*mParamNameMap)[mParams[i]->mName] = i - startIdx; } +bool BfMethodDef::CanReflect() +{ + if (mMethodDeclaration != NULL) + return true; + if (mMethodType == BfMethodType_Ctor) + return true; + return false; +} + /// void BfTypeDef::Reset() diff --git a/IDEHelper/Compiler/BfSystem.h b/IDEHelper/Compiler/BfSystem.h index 271e0996..c0609167 100644 --- a/IDEHelper/Compiler/BfSystem.h +++ b/IDEHelper/Compiler/BfSystem.h @@ -240,6 +240,12 @@ enum BfMethodFlags BfMethodFlags_Constructor = 0x8000 }; +enum BfComptimeMethodFlags +{ + BfComptimeMethodFlags_None = 0, + BfComptimeMethodFlags_NoReflect = 1 +}; + enum BfObjectFlags : uint8 { BfObjectFlag_None = 0, @@ -970,8 +976,10 @@ public: bool IsDefaultCtor(); bool IsCtorOrInit(); String ToString(); + String GetReflectName(); int GetExplicitParamCount(); void BuildParamNameMap(); + bool CanReflect(); }; class BfOperatorDef : public BfMethodDef diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 6173cddf..a1a01aa5 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -6220,7 +6220,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* return false; } - CeSetAddrVal(stackPtr + 0, GetString(methodInstance->mMethodDef->mName), ptrSize); + CeSetAddrVal(stackPtr + 0, GetString(methodInstance->mMethodDef->GetReflectName()), ptrSize); _FixVariables(); } else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetInfo) @@ -6231,7 +6231,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* // int16 mFlags // int32 mMethodIdx - int64 methodHandle = *(int64*)((uint8*)stackPtr + 4+4+4+2+4); + int64 methodHandle = *(int64*)((uint8*)stackPtr + 4+4+4+2+1+4); auto methodInstance = mCeMachine->GetMethodInstance(methodHandle); if (methodInstance == NULL) @@ -6248,7 +6248,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* *(int32*)(stackPtr + 4) = methodInstance->GetParamCount(); *(int32*)(stackPtr + 4+4) = genericArgCount; *(int16*)(stackPtr + 4+4+4) = methodInstance->GetMethodFlags(); - *(int32*)(stackPtr + 4+4+4+2) = methodInstance->mMethodDef->mIdx; + *(int32*)(stackPtr + 4+4+4+2) = methodInstance->GetComptimeMethodFlags(); + *(int32*)(stackPtr + 4+4+4+2+1) = methodInstance->mMethodDef->mIdx; } else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetParamInfo) { diff --git a/IDEHelper/Tests/src/Reflection.bf b/IDEHelper/Tests/src/Reflection.bf index ddad562a..a66fa50c 100644 --- a/IDEHelper/Tests/src/Reflection.bf +++ b/IDEHelper/Tests/src/Reflection.bf @@ -278,10 +278,10 @@ namespace Tests switch (methodIdx) { case 0: - Test.Assert(methodInfo.Name == "__BfCtor"); + Test.Assert(methodInfo.Name == "this"); Test.Assert(methodInfo.IsConstructor); case 1: - Test.Assert(methodInfo.Name == "__BfStaticCtor"); + Test.Assert(methodInfo.Name == "this"); Test.Assert(methodInfo.IsConstructor); case 2: Test.Assert(methodInfo.Name == "GetA"); @@ -509,7 +509,7 @@ namespace Tests switch (methodIdx) { case 0: - Test.Assert(methodInfo.Name == "__BfCtor"); + Test.Assert(methodInfo.Name == "this"); case 1: Test.Assert(methodInfo.Name == "GetA");