#pragma once // Step 526: Symbol Scope Extractor #include #include #include #include #include struct ScopedSymbol { std::string name; std::string kind; int scopeDepth = 0; }; struct ScopeSnapshot { bool supported = false; std::vector candidates; }; class SymbolScopeExtractor { public: SymbolScopeExtractor() { initDefaults(); } void registerRule(const std::string& language, const std::string& nodeKind, const std::vector& allowedKinds) { rules_[key(language, nodeKind)] = std::set(allowedKinds.begin(), allowedKinds.end()); } ScopeSnapshot buildSnapshot(const std::string& language, const std::string& nodeKind, const std::vector& visible, const std::set& forbidden = {}) const { auto it = rules_.find(key(language, nodeKind)); if (it == rules_.end()) return {}; std::map selectedByName; for (const auto& symbol : visible) { if (it->second.count(symbol.kind) == 0) continue; if (forbidden.count(symbol.name) != 0) continue; auto existing = selectedByName.find(symbol.name); if (existing == selectedByName.end() || symbol.scopeDepth > existing->second.scopeDepth) { selectedByName[symbol.name] = symbol; } } ScopeSnapshot snapshot; snapshot.supported = true; for (const auto& entry : selectedByName) { snapshot.candidates.push_back(entry.second); } return snapshot; } std::vector unresolvedSymbols( const ScopeSnapshot& snapshot, const std::vector& requestedSymbols) const { std::set candidateNames; for (const auto& symbol : snapshot.candidates) { candidateNames.insert(symbol.name); } std::set unresolved; for (const auto& requested : requestedSymbols) { if (candidateNames.count(requested) == 0) { unresolved.insert(requested); } } return std::vector(unresolved.begin(), unresolved.end()); } bool canApply(const ScopeSnapshot& snapshot, const std::vector& requestedSymbols) const { if (!snapshot.supported) return false; return unresolvedSymbols(snapshot, requestedSymbols).empty(); } private: std::map> rules_; static std::string key(const std::string& language, const std::string& nodeKind) { return language + "::" + nodeKind; } void initDefaults() { registerRule("cpp", "Function", {"Function", "Variable", "Parameter", "Type", "Namespace"}); registerRule("cpp", "Class", {"Method", "Field", "Type", "Namespace"}); registerRule("python", "Function", {"Function", "Variable", "Parameter", "Class"}); registerRule("python", "Class", {"Function", "Variable", "Class"}); registerRule("typescript", "Function", {"Function", "Variable", "Parameter", "Type", "Import"}); registerRule("typescript", "Class", {"Function", "Variable", "Type", "Import"}); registerRule("rust", "Function", {"Function", "Variable", "Parameter", "Type", "Trait"}); registerRule("go", "Function", {"Function", "Variable", "Parameter", "Type", "Import"}); } };