diff options
| author | Yong He <yonghe@outlook.com> | 2025-08-06 01:07:41 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-06 08:07:41 +0000 |
| commit | 68b0125226464cb3c9e9b7f50bfb53cda97723b4 (patch) | |
| tree | 5f0833c6d9aa759b2769f7f6ac9b3ca6ed9a10f0 /source/slang/slang-linkable.cpp | |
| parent | 83675103a1a4fefde11b314aed26f4d37860efe7 (diff) | |
Add reflection api for overload candidate filtering. (#8066)
* Add reflection api for overload candidate filtering.
* Fix API.
* Fix.
* Update build.
* Update test.
* Update formatting.
Diffstat (limited to 'source/slang/slang-linkable.cpp')
| -rw-r--r-- | source/slang/slang-linkable.cpp | 59 |
1 files changed, 34 insertions, 25 deletions
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<OverloadedExpr>(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<FunctionDeclBase>(item.declRef.getDecl())) + LookupResult filteredResult; + for (auto candidate : overloadedExpr->lookupResult2) { - allAreFunctions = false; - break; + if (as<InterfaceDecl>(getParentDecl(candidate.declRef.getDecl()))) + { + if (!candidate.declRef.getDecl() + ->hasModifier<HasInterfaceDefaultImplModifier>()) + 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<OverloadedExpr>(resolvedTerm)) - { return overloadedExpr; } - if (auto declRefExpr = as<DeclRefExpr>(resolvedTerm)) + if (auto declRefExpr = as<DeclRefExpr>(checkedTerm)) { return declRefExpr; } |
