Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/Analysis/include/Luau/FragmentAutocomplete.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/Ast.h"
5
#include "Luau/Parser.h"
6
#include "Luau/AutocompleteTypes.h"
7
#include "Luau/DenseHash.h"
8
#include "Luau/Module.h"
9
#include "Luau/Frontend.h"
10
11
#include <memory>
12
#include <vector>
13
14
namespace Luau
15
{
16
struct FrontendOptions;
17
18
enum class FragmentAutocompleteWaypoint
19
{
20
ParseFragmentEnd,
21
CloneModuleStart,
22
CloneModuleEnd,
23
DfgBuildEnd,
24
CloneAndSquashScopeStart,
25
CloneAndSquashScopeEnd,
26
ConstraintSolverStart,
27
ConstraintSolverEnd,
28
TypecheckFragmentEnd,
29
AutocompleteEnd,
30
COUNT,
31
};
32
33
class IFragmentAutocompleteReporter
34
{
35
public:
36
virtual void reportWaypoint(FragmentAutocompleteWaypoint) = 0;
37
virtual void reportFragmentString(std::string_view) = 0;
38
};
39
40
enum class FragmentTypeCheckStatus
41
{
42
SkipAutocomplete,
43
Success,
44
};
45
46
struct FragmentAutocompleteAncestryResult
47
{
48
DenseHashMap<AstName, AstLocal*> localMap{AstName()};
49
std::vector<AstLocal*> localStack;
50
std::vector<AstNode*> ancestry;
51
AstStat* nearestStatement = nullptr;
52
AstStatBlock* parentBlock = nullptr;
53
Location fragmentSelectionRegion;
54
};
55
56
struct FragmentParseResult
57
{
58
std::string fragmentToParse;
59
AstStatBlock* root = nullptr;
60
std::vector<AstNode*> ancestry;
61
AstStat* nearestStatement = nullptr;
62
std::vector<Comment> commentLocations;
63
std::unique_ptr<Allocator> alloc = std::make_unique<Allocator>();
64
Position scopePos{0, 0};
65
};
66
67
struct FragmentTypeCheckResult
68
{
69
ModulePtr incrementalModule = nullptr;
70
ScopePtr freshScope;
71
std::vector<AstNode*> ancestry;
72
};
73
74
struct FragmentAutocompleteResult
75
{
76
ModulePtr incrementalModule;
77
Scope* freshScope;
78
AutocompleteResult acResults;
79
};
80
81
struct FragmentRegion
82
{
83
Location fragmentLocation;
84
AstStat* nearestStatement = nullptr; // used for tests
85
AstStatBlock* parentBlock = nullptr; // used for scope detection
86
};
87
88
std::optional<Position> blockDiffStart(AstStatBlock* blockOld, AstStatBlock* blockNew, AstStat* nearestStatementNewAst);
89
FragmentRegion getFragmentRegion(AstStatBlock* root, const Position& cursorPosition);
90
FragmentAutocompleteAncestryResult findAncestryForFragmentParse(AstStatBlock* stale, const Position& cursorPos, AstStatBlock* lastGoodParse);
91
FragmentAutocompleteAncestryResult findAncestryForFragmentParse_DEPRECATED(AstStatBlock* root, const Position& cursorPos);
92
93
std::optional<FragmentParseResult> parseFragment_DEPRECATED(
94
AstStatBlock* root,
95
AstNameTable* names,
96
std::string_view src,
97
const Position& cursorPos,
98
std::optional<Position> fragmentEndPosition
99
);
100
101
std::optional<FragmentParseResult> parseFragment(
102
AstStatBlock* stale,
103
AstStatBlock* mostRecentParse,
104
AstNameTable* names,
105
std::string_view src,
106
const Position& cursorPos,
107
std::optional<Position> fragmentEndPosition
108
);
109
110
std::pair<FragmentTypeCheckStatus, FragmentTypeCheckResult> typecheckFragment(
111
Frontend& frontend,
112
const ModuleName& moduleName,
113
const Position& cursorPos,
114
std::optional<FrontendOptions> opts,
115
std::string_view src,
116
std::optional<Position> fragmentEndPosition,
117
AstStatBlock* recentParse = nullptr,
118
IFragmentAutocompleteReporter* reporter = nullptr
119
);
120
121
FragmentAutocompleteResult fragmentAutocomplete(
122
Frontend& frontend,
123
std::string_view src,
124
const ModuleName& moduleName,
125
Position cursorPosition,
126
std::optional<FrontendOptions> opts,
127
StringCompletionCallback callback,
128
std::optional<Position> fragmentEndPosition = std::nullopt,
129
AstStatBlock* recentParse = nullptr,
130
IFragmentAutocompleteReporter* reporter = nullptr,
131
bool isInHotComment = false
132
);
133
134
enum class FragmentAutocompleteStatus
135
{
136
Success,
137
FragmentTypeCheckFail,
138
InternalIce
139
};
140
141
struct FragmentAutocompleteStatusResult
142
{
143
FragmentAutocompleteStatus status;
144
std::optional<FragmentAutocompleteResult> result;
145
};
146
147
struct FragmentContext
148
{
149
std::string_view newSrc;
150
const ParseResult& freshParse;
151
std::optional<FrontendOptions> opts;
152
std::optional<Position> DEPRECATED_fragmentEndPosition;
153
IFragmentAutocompleteReporter* reporter = nullptr;
154
};
155
156
/**
157
* @brief Attempts to compute autocomplete suggestions from the fragment context.
158
*
159
* This function computes autocomplete suggestions using outdated frontend typechecking data
160
* by patching the fragment context of the new script source content.
161
*
162
* @param frontend The Luau Frontend data structure, which may contain outdated typechecking data.
163
*
164
* @param moduleName The name of the target module, specifying which script the caller wants to request autocomplete for.
165
*
166
* @param cursorPosition The position in the script where the caller wants to trigger autocomplete.
167
*
168
* @param context The fragment context that this API will use to patch the outdated typechecking data.
169
*
170
* @param stringCompletionCB A callback function that provides autocomplete suggestions for string contexts.
171
*
172
* @return
173
* The status indicating whether `fragmentAutocomplete` ran successfully or failed, along with the reason for failure.
174
* Also includes autocomplete suggestions if the status is successful.
175
*
176
* @usage
177
* FragmentAutocompleteStatusResult acStatusResult;
178
* if (shouldFragmentAC)
179
* acStatusResult = Luau::tryFragmentAutocomplete(...);
180
*
181
* if (acStatusResult.status != Successful)
182
* {
183
* frontend.check(moduleName, options);
184
* acStatusResult.acResult = Luau::autocomplete(...);
185
* }
186
* return convertResultWithContext(acStatusResult.acResult);
187
*/
188
FragmentAutocompleteStatusResult tryFragmentAutocomplete(
189
Frontend& frontend,
190
const ModuleName& moduleName,
191
Position cursorPosition,
192
FragmentContext context,
193
StringCompletionCallback stringCompletionCB
194
);
195
196
} // namespace Luau
197
198