diff options
| author | Sai Praveen Bangaru <31557731+saipraveenb25@users.noreply.github.com> | 2024-08-07 02:04:37 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-07 02:04:37 -0400 |
| commit | 2f2ae8c31490ab01ce0d0cc76d5d7fcf1d21efe7 (patch) | |
| tree | 135cb2109f2717dba3a11929c4cdf163b5ad5c50 /source/slang/slang.cpp | |
| parent | 366c9b4526b4b940c8aafce459d6784211e862bc (diff) | |
More reflection API features. (#4740)
* More reflection API features.
+ Lookup methods and members (by string) on types
+ Fix issue with looking up non-static members through the scope operator '::'
+ `GenericReflection`: Cast a decl to generic to access unspecialized generic parameter names and constraints
+ `GenericReflection`: Use `getGenericContainer()` from function, variable or type to access the 'nearest' generic parent along with specialization info
+ `GenericReflection::getConcreteType` and `GenericReflection::getConcreteIntVal`: to get the concrete type of a param in the context of the reflection object
+ `GenericReflection::getOuterGenericContainer` to go up one level and get the outer generic declarations (if there are more than one enclosing generic scopes)
+ `DeclReflection::getParent`: go to parent declaration.
+ Change `VariableReflection` to be a `DeclRef` rather than a decl (allows us to return properly substituted types for methods, members, and more)
* Fix Falcor issue
Diffstat (limited to 'source/slang/slang.cpp')
| -rw-r--r-- | source/slang/slang.cpp | 87 |
1 files changed, 86 insertions, 1 deletions
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index cf8c19033..9ba02ee50 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -26,6 +26,8 @@ #include "slang-parser.h" #include "slang-preprocessor.h" #include "slang-type-layout.h" +#include "slang-lookup.h" + # #include "slang-options.h" @@ -2279,7 +2281,10 @@ DeclRef<Decl> ComponentType::findDeclFromString( linkage, nullptr, sink); - SemanticsVisitor visitor(&sharedSemanticsContext); + SemanticsContext context(&sharedSemanticsContext); + context = context.allowStaticReferenceToNonStaticMember(); + + SemanticsVisitor visitor(context); auto checkedExpr = visitor.CheckExpr(expr); if (auto declRefExpr = as<DeclRefExpr>(checkedExpr)) @@ -2291,6 +2296,86 @@ DeclRef<Decl> ComponentType::findDeclFromString( return result; } +DeclRef<Decl> ComponentType::findDeclFromStringInType( + Type* type, + String const& name, + LookupMask mask, + DiagnosticSink* sink) +{ + DeclRef<Decl> result; + + // Only look up in the type if it is a DeclRefType + if (!as<DeclRefType>(type)) + return DeclRef<Decl>(); + + // TODO(JS): For now just used the linkages ASTBuilder to keep on scope + // + // The parseTermString uses the linkage ASTBuilder for it's parsing. + // + // It might be possible to just create a temporary ASTBuilder - the worry though is + // that the parsing sets a member variable in AST node to one of these scopes, and then + // it become a dangling pointer. So for now we go with the linkages. + auto astBuilder = getLinkage()->getASTBuilder(); + + // Otherwise, we need to start looking in + // the modules that were directly or + // indirectly referenced. + // + Scope* scope = _getOrCreateScopeForLegacyLookup(astBuilder); + + auto linkage = getLinkage(); + + SLANG_AST_BUILDER_RAII(linkage->getASTBuilder()); + + Expr* expr = linkage->parseTermString(name, scope); + + SharedSemanticsContext sharedSemanticsContext( + linkage, + nullptr, + sink); + SemanticsContext context(&sharedSemanticsContext); + context = context.allowStaticReferenceToNonStaticMember(); + + SemanticsVisitor visitor(context); + + GenericAppExpr* genericOuterExpr = nullptr; + if (as<GenericAppExpr>(expr)) + { + // Unwrap the generic application, and re-wrap it around the static-member expr + genericOuterExpr = as<GenericAppExpr>(expr); + expr = genericOuterExpr->functionExpr; + } + + if (!as<VarExpr>(expr)) + return result; + + auto rs = astBuilder->create<StaticMemberExpr>(); + auto typeExpr = astBuilder->create<SharedTypeExpr>(); + auto typetype = astBuilder->getOrCreate<TypeType>(type); + typeExpr->type = typetype; + rs->baseExpression = typeExpr; + rs->name = as<VarExpr>(expr)->name; + + expr = rs; + + // If we have a generic-app expression, re-wrap the static-member expr + if (genericOuterExpr) + { + genericOuterExpr->functionExpr = expr; + expr = genericOuterExpr; + } + + auto checkedTerm = visitor.CheckTerm(expr); + auto resolvedTerm = visitor.maybeResolveOverloadedExpr(checkedTerm, mask, sink); + + if (auto declRefExpr = as<DeclRefExpr>(resolvedTerm)) + { + result = declRefExpr->declRef; + } + + return result; +} + static void collectExportedConstantInContainer( Dictionary<String, IntVal*>& dict, ASTBuilder* builder, |
