From 68b0125226464cb3c9e9b7f50bfb53cda97723b4 Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 6 Aug 2025 01:07:41 -0700 Subject: Add reflection api for overload candidate filtering. (#8066) * Add reflection api for overload candidate filtering. * Fix API. * Fix. * Update build. * Update test. * Update formatting. --- source/slang/slang-linkable.cpp | 59 ++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 25 deletions(-) (limited to 'source/slang/slang-linkable.cpp') diff --git a/source/slang/slang-linkable.cpp b/source/slang/slang-linkable.cpp index da4cec823..f7dc28171 100644 --- a/source/slang/slang-linkable.cpp +++ b/source/slang/slang-linkable.cpp @@ -8,6 +8,7 @@ #include "core/slang-memory-file-system.h" #include "slang-check-impl.h" #include "slang-compiler.h" +#include "slang-lookup.h" #include "slang-mangle.h" namespace Slang @@ -772,6 +773,14 @@ Type* ComponentType::getTypeFromString(String const& typeStr, DiagnosticSink* si return type; } +Expr* ComponentType::tryResolveOverloadedExpr(Expr* exprIn) +{ + auto linkage = getLinkage(); + SemanticsContext context(linkage->getSemanticsForReflection()); + SemanticsVisitor visitor(context); + return visitor.maybeResolveOverloadedExpr(exprIn, LookupMask::Function, nullptr); +} + Expr* ComponentType::findDeclFromString(String const& name, DiagnosticSink* sink) { // If we've looked up this type name before, @@ -905,39 +914,39 @@ Expr* ComponentType::findDeclFromStringInType( auto checkedTerm = visitor.CheckTerm(expr); - // Check if checkedTerm is overloaded functions and avoid resolving if so - // to preserve all function overloads with different signatures - Expr* resolvedTerm = checkedTerm; if (auto overloadedExpr = as(checkedTerm)) { - // Check if all candidates are function references - bool allAreFunctions = true; - for (auto item : overloadedExpr->lookupResult2.items) + // For functions, since we don't know the argument list yet, we will have to defer + // non-parameter-related candidate comparison logic into its separate step. + if (mask != LookupMask::Function) + return visitor.maybeResolveOverloadedExpr(checkedTerm, mask, nullptr); + overloadedExpr->lookupResult2 = refineLookup(overloadedExpr->lookupResult2, mask); + + // Filter out abstract base interface method implementations for reflection. + if (!isInterfaceType(type)) { - if (!as(item.declRef.getDecl())) + LookupResult filteredResult; + for (auto candidate : overloadedExpr->lookupResult2) { - allAreFunctions = false; - break; + if (as(getParentDecl(candidate.declRef.getDecl()))) + { + if (!candidate.declRef.getDecl() + ->hasModifier()) + continue; + } + AddToLookupResult(filteredResult, candidate); } + if (filteredResult.isValid() && !filteredResult.isOverloaded()) + { + // If there are exactly one candidate after filtering, we can + // safely return resolved expr. + return visitor.maybeResolveOverloadedExpr(checkedTerm, mask, nullptr); + } + overloadedExpr->lookupResult2 = filteredResult; } - - // If not all are functions, resolve the overload as usual - if (!allAreFunctions) - { - resolvedTerm = visitor.maybeResolveOverloadedExpr(checkedTerm, mask, sink); - } - } - else - { - // Not overloaded, resolve as usual - resolvedTerm = visitor.maybeResolveOverloadedExpr(checkedTerm, mask, sink); - } - - if (auto overloadedExpr = as(resolvedTerm)) - { return overloadedExpr; } - if (auto declRefExpr = as(resolvedTerm)) + if (auto declRefExpr = as(checkedTerm)) { return declRefExpr; } -- cgit v1.2.3