22
33#include " Luau/RequireNavigator.h"
44
5+ #include " AliasCycleTracker.h"
56#include " PathUtilities.h"
67
78#include " Luau/Config.h"
@@ -76,10 +77,11 @@ Error Navigator::navigateImpl(std::string_view path)
7677 }
7778 );
7879
79- if (Error error = navigateToAndPopulateConfig (alias))
80+ Config config;
81+ if (Error error = navigateToAndPopulateConfig (alias, config))
8082 return error;
8183
82- if (!foundAliasValue )
84+ if (!config. aliases . contains (alias) )
8385 {
8486 if (alias != " self" )
8587 return " @" + alias + " is not a valid alias" ;
@@ -94,7 +96,7 @@ Error Navigator::navigateImpl(std::string_view path)
9496 return std::nullopt ;
9597 }
9698
97- if (Error error = navigateToAlias (alias, *foundAliasValue ))
99+ if (Error error = navigateToAlias (alias, config, {} ))
98100 return error;
99101 if (Error error = navigateThroughPath (path))
100102 return error;
@@ -146,8 +148,9 @@ Error Navigator::navigateThroughPath(std::string_view path)
146148 return std::nullopt ;
147149}
148150
149- Error Navigator::navigateToAlias (const std::string& alias, const std::string& value )
151+ Error Navigator::navigateToAlias (const std::string& alias, const Config& config, AliasCycleTracker cycleTracker )
150152{
153+ std::string value = config.aliases .find (alias)->value ;
151154 PathType pathType = getPathType (value);
152155
153156 if (pathType == PathType::RelativeToCurrent || pathType == PathType::RelativeToParent)
@@ -157,7 +160,33 @@ Error Navigator::navigateToAlias(const std::string& alias, const std::string& va
157160 }
158161 else if (pathType == PathType::Aliased)
159162 {
160- return " alias \" @" + alias + " \" cannot point to an aliased path (\" " + value + " \" )" ;
163+ if (Error error = cycleTracker.add (alias))
164+ return error;
165+
166+ std::string nextAlias = extractAlias (value);
167+ if (config.aliases .contains (nextAlias))
168+ {
169+ if (Error error = navigateToAlias (nextAlias, config, std::move (cycleTracker)))
170+ return error;
171+ }
172+ else
173+ {
174+ Config parentConfig;
175+ if (Error error = navigateToAndPopulateConfig (nextAlias, parentConfig))
176+ return error;
177+ if (parentConfig.aliases .contains (nextAlias))
178+ {
179+ if (Error error = navigateToAlias (nextAlias, parentConfig, {}))
180+ return error;
181+ }
182+ else
183+ {
184+ return " @" + nextAlias + " is not a valid alias" ;
185+ }
186+ }
187+
188+ if (Error error = navigateThroughPath (value))
189+ return error;
161190 }
162191 else
163192 {
@@ -168,11 +197,9 @@ Error Navigator::navigateToAlias(const std::string& alias, const std::string& va
168197 return std::nullopt ;
169198}
170199
171- Error Navigator::navigateToAndPopulateConfig (const std::string& desiredAlias)
200+ Error Navigator::navigateToAndPopulateConfig (const std::string& desiredAlias, Config& config )
172201{
173- Luau::Config config;
174-
175- while (!foundAliasValue)
202+ while (!config.aliases .contains (desiredAlias))
176203 {
177204 NavigationContext::NavigateResult result = navigationContext.toParent ();
178205 if (result == NavigationContext::NavigateResult::Ambiguous)
@@ -193,7 +220,7 @@ Error Navigator::navigateToAndPopulateConfig(const std::string& desiredAlias)
193220 {
194221 if (navigationContext.getConfigBehavior () == NavigationContext::ConfigBehavior::GetAlias)
195222 {
196- foundAliasValue = navigationContext.getAlias (desiredAlias);
223+ config. setAlias (desiredAlias, * navigationContext.getAlias (desiredAlias), /* configLocation = */ " unused " );
197224 break ;
198225 }
199226
@@ -221,9 +248,6 @@ Error Navigator::navigateToAndPopulateConfig(const std::string& desiredAlias)
221248 if (Error error = Luau::extractLuauConfig (*configContents, config, std::move (opts.aliasOptions ), std::move (callbacks)))
222249 return error;
223250 }
224-
225- if (config.aliases .contains (desiredAlias))
226- foundAliasValue = config.aliases [desiredAlias].value ;
227251 }
228252 };
229253
0 commit comments