1#include "grammarDependencies.h"
9static void collectExternalReferencesInRules(
10 const std::vector<IRawRule*>& rules,
11 IRawGrammar* baseGrammar,
12 IRawGrammar* selfGrammar,
13 std::vector<AbsoluteRuleReference>& result,
14 std::set<IRawRule*>& visitedRules
18static void collectExternalReferencesInRule(
20 IRawGrammar* baseGrammar,
21 IRawGrammar* selfGrammar,
22 std::vector<AbsoluteRuleReference>& result,
23 std::set<IRawRule*>& visitedRules
25 if (!rule || visitedRules.find(rule) != visitedRules.end()) {
28 visitedRules.insert(rule);
31 if (rule->include && !rule->include->empty()) {
32 IncludeReference ref = parseInclude(*rule->include);
34 if (ref.kind == IncludeReferenceKind::TopLevelReference) {
36 if (ref.scopeName != selfGrammar->scopeName && ref.scopeName != baseGrammar->scopeName) {
37 result.push_back(AbsoluteRuleReference(ref.scopeName,
""));
39 }
else if (ref.kind == IncludeReferenceKind::TopLevelRepositoryReference) {
41 if (ref.scopeName != selfGrammar->scopeName && ref.scopeName != baseGrammar->scopeName) {
42 result.push_back(AbsoluteRuleReference(ref.scopeName, ref.ruleName));
44 }
else if (ref.kind == IncludeReferenceKind::RelativeReference) {
46 if (selfGrammar->repository) {
47 IRawRule* referencedRule = selfGrammar->repository->getRule(ref.ruleName);
49 collectExternalReferencesInRule(referencedRule, baseGrammar, selfGrammar, result, visitedRules);
56 if (rule->patterns && !rule->patterns->empty()) {
57 collectExternalReferencesInRules(*rule->patterns, baseGrammar, selfGrammar, result, visitedRules);
61static void collectExternalReferencesInRules(
62 const std::vector<IRawRule*>& rules,
63 IRawGrammar* baseGrammar,
64 IRawGrammar* selfGrammar,
65 std::vector<AbsoluteRuleReference>& result,
66 std::set<IRawRule*>& visitedRules
68 for (IRawRule* rule : rules) {
69 collectExternalReferencesInRule(rule, baseGrammar, selfGrammar, result, visitedRules);
73IncludeReference parseInclude(
const std::string& include) {
74 if (include ==
"$base" || include ==
"$self") {
75 return IncludeReference(
76 include ==
"$base" ? IncludeReferenceKind::Base : IncludeReferenceKind::Self
80 if (include[0] ==
'#') {
82 return IncludeReference(
83 IncludeReferenceKind::RelativeReference,
89 size_t sharpIndex = include.find(
'#');
90 if (sharpIndex != std::string::npos) {
92 return IncludeReference(
93 IncludeReferenceKind::TopLevelRepositoryReference,
94 include.substr(0, sharpIndex),
95 include.substr(sharpIndex + 1)
100 return IncludeReference(
101 IncludeReferenceKind::TopLevelReference,
107ScopeDependencyProcessor::ScopeDependencyProcessor(SyncRegistry* repo,
const std::string& initialScopeName)
108 : _repo(repo), _initialScopeName(initialScopeName) {
109 _seenScopes.insert(initialScopeName);
110 Q.push(AbsoluteRuleReference(initialScopeName,
""));
113void ScopeDependencyProcessor::processQueue() {
115 std::queue<AbsoluteRuleReference> currentQ;
119 std::vector<AbsoluteRuleReference> externalRefs;
120 std::set<IRawRule*> visitedRules;
122 while (!currentQ.empty()) {
123 AbsoluteRuleReference ref = currentQ.front();
127 IRawGrammar* grammar = _repo->lookup(ref.scopeName);
134 if (grammar->patterns && !grammar->patterns->empty()) {
135 collectExternalReferencesInRules(*grammar->patterns, grammar, grammar, externalRefs, visitedRules);
139 if (grammar->injections) {
140 for (
const auto& injection : *grammar->injections) {
141 if (injection.second->patterns) {
142 collectExternalReferencesInRules(*injection.second->patterns, grammar, grammar, externalRefs, visitedRules);
150 for (
const AbsoluteRuleReference& extRef : externalRefs) {
151 std::string key = extRef.scopeName;
152 if (!extRef.ruleName.empty()) {
153 key +=
"#" + extRef.ruleName;
157 if (_seenScopes.find(key) == _seenScopes.end()) {
158 _seenScopes.insert(key);