Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/Require/include/Luau/RequireNavigator.h
2727 views
1
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2
#pragma once
3
4
#include "Luau/Config.h"
5
#include "Luau/LuauConfig.h"
6
7
#include <functional>
8
#include <optional>
9
#include <string>
10
#include <string_view>
11
12
struct lua_State;
13
14
////////////////////////////////////////////////////////////////////////////////
15
//
16
// This file provides a C++ interface for navigating the context in which
17
// require-by-string operates. This is used internally by the require-by-string
18
// runtime library to resolve paths based on the rules defined by its consumers.
19
//
20
// Including this file directly allows for inspection of the require-by-string
21
// path resolution algorithm's behavior without enabling the runtime library,
22
// which can be useful for static tooling.
23
//
24
////////////////////////////////////////////////////////////////////////////////
25
26
namespace Luau::Require
27
{
28
29
class AliasCycleTracker;
30
31
// The ErrorHandler interface is used to report errors during navigation.
32
// The default implementation does nothing but can be overridden to enable
33
// custom error handling behavior.
34
class ErrorHandler
35
{
36
public:
37
virtual ~ErrorHandler() = default;
38
virtual void reportError(std::string message) {}
39
};
40
41
// NavigationContext is an pure virtual class that is intended to be implemented
42
// and injected into a Navigator.
43
//
44
// When a Navigator traverses a require path, its NavigationContext's methods
45
// are invoked, with the expectation that the NavigationContext will keep track
46
// of the current state of the navigation and provide information about the
47
// current context as needed.
48
class NavigationContext
49
{
50
public:
51
virtual ~NavigationContext() = default;
52
53
enum class NavigateResult
54
{
55
Success,
56
Ambiguous,
57
NotFound
58
};
59
60
virtual NavigateResult resetToRequirer() = 0;
61
virtual NavigateResult jumpToAlias(const std::string& path) = 0;
62
63
virtual NavigateResult toAliasOverride(const std::string& aliasUnprefixed)
64
{
65
return NavigateResult::NotFound;
66
};
67
virtual NavigateResult toAliasFallback(const std::string& aliasUnprefixed)
68
{
69
return NavigateResult::NotFound;
70
};
71
72
virtual NavigateResult toParent() = 0;
73
virtual NavigateResult toChild(const std::string& component) = 0;
74
75
enum class ConfigBehavior
76
{
77
GetAlias,
78
GetConfig
79
};
80
81
enum class ConfigStatus
82
{
83
Absent,
84
Ambiguous,
85
PresentJson,
86
PresentLuau
87
};
88
89
virtual ConfigStatus getConfigStatus() const = 0;
90
91
std::function<void(lua_State*)> luauConfigInit = nullptr;
92
void (*luauConfigInterrupt)(lua_State* L, int gc) = nullptr;
93
94
// The result of getConfigBehavior determines whether getAlias or getConfig
95
// is called when getConfigStatus indicates a configuration is present.
96
virtual ConfigBehavior getConfigBehavior() const = 0;
97
virtual std::optional<std::string> getAlias(const std::string& alias) const = 0;
98
virtual std::optional<std::string> getConfig() const = 0;
99
};
100
101
// The Navigator class is responsible for traversing a given require path in the
102
// context of a given NavigationContext.
103
//
104
// The Navigator is not intended to be overridden. Rather, it expects a custom
105
// injected NavigationContext that provides the desired navigation behavior.
106
class Navigator
107
{
108
public:
109
enum class Status
110
{
111
Success,
112
ErrorReported
113
};
114
115
Navigator(NavigationContext& navigationContext, ErrorHandler& errorHandler);
116
[[nodiscard]] Status navigate(std::string path);
117
118
private:
119
using Error = std::optional<std::string>;
120
[[nodiscard]] Error navigateImpl(std::string_view path);
121
[[nodiscard]] Error navigateThroughPath(std::string_view path);
122
[[nodiscard]] Error navigateToAlias(const std::string& alias, const Config& config, AliasCycleTracker cycleTracker);
123
[[nodiscard]] Error navigateToAndPopulateConfig(const std::string& desiredAlias, Config& config);
124
125
[[nodiscard]] Error resetToRequirer();
126
[[nodiscard]] Error jumpToAlias(const std::string& aliasPath);
127
[[nodiscard]] Error navigateToParent(std::optional<std::string> previousComponent);
128
[[nodiscard]] Error navigateToChild(const std::string& component);
129
130
[[nodiscard]] std::pair<Error, bool> toAliasOverride(const std::string& aliasUnprefixed);
131
[[nodiscard]] Error toAliasFallback(const std::string& aliasUnprefixed);
132
133
NavigationContext& navigationContext;
134
ErrorHandler& errorHandler;
135
};
136
137
} // namespace Luau::Require
138
139