2022-09-08 23:14:25 +01:00
|
|
|
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "Luau/Constraint.h"
|
|
|
|
#include "Luau/NotNull.h"
|
|
|
|
#include "Luau/Scope.h"
|
2023-02-24 21:49:38 +00:00
|
|
|
#include "Luau/Module.h"
|
2022-09-08 23:14:25 +01:00
|
|
|
#include "Luau/ToString.h"
|
|
|
|
#include "Luau/Error.h"
|
|
|
|
#include "Luau/Variant.h"
|
|
|
|
|
|
|
|
#include <optional>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
namespace Luau
|
|
|
|
{
|
|
|
|
|
|
|
|
struct ErrorSnapshot
|
|
|
|
{
|
|
|
|
std::string message;
|
|
|
|
Location location;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BindingSnapshot
|
|
|
|
{
|
|
|
|
std::string typeId;
|
|
|
|
std::string typeString;
|
|
|
|
Location location;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TypeBindingSnapshot
|
|
|
|
{
|
|
|
|
std::string typeId;
|
|
|
|
std::string typeString;
|
|
|
|
};
|
|
|
|
|
2023-02-24 21:49:38 +00:00
|
|
|
struct ExprTypesAtLocation
|
|
|
|
{
|
|
|
|
Location location;
|
|
|
|
TypeId ty;
|
|
|
|
std::optional<TypeId> expectedTy;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct AnnotationTypesAtLocation
|
|
|
|
{
|
|
|
|
Location location;
|
|
|
|
TypeId resolvedTy;
|
|
|
|
};
|
|
|
|
|
2022-09-08 23:14:25 +01:00
|
|
|
struct ConstraintGenerationLog
|
|
|
|
{
|
|
|
|
std::string source;
|
|
|
|
std::vector<ErrorSnapshot> errors;
|
2023-02-24 21:49:38 +00:00
|
|
|
|
|
|
|
std::vector<ExprTypesAtLocation> exprTypeLocations;
|
|
|
|
std::vector<AnnotationTypesAtLocation> annotationTypeLocations;
|
2022-09-08 23:14:25 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
struct ScopeSnapshot
|
|
|
|
{
|
|
|
|
std::unordered_map<Name, BindingSnapshot> bindings;
|
|
|
|
std::unordered_map<Name, TypeBindingSnapshot> typeBindings;
|
|
|
|
std::unordered_map<Name, TypeBindingSnapshot> typePackBindings;
|
|
|
|
std::vector<ScopeSnapshot> children;
|
|
|
|
};
|
|
|
|
|
2023-02-24 21:49:38 +00:00
|
|
|
using ConstraintBlockTarget = Variant<TypeId, TypePackId, NotNull<const Constraint>>;
|
2022-09-08 23:14:25 +01:00
|
|
|
|
|
|
|
struct ConstraintBlock
|
|
|
|
{
|
2023-02-24 21:49:38 +00:00
|
|
|
ConstraintBlockTarget target;
|
2022-09-08 23:14:25 +01:00
|
|
|
std::string stringification;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ConstraintSnapshot
|
|
|
|
{
|
|
|
|
std::string stringification;
|
2023-02-10 19:40:38 +00:00
|
|
|
Location location;
|
2022-09-08 23:14:25 +01:00
|
|
|
std::vector<ConstraintBlock> blocks;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BoundarySnapshot
|
|
|
|
{
|
2023-02-24 21:49:38 +00:00
|
|
|
DenseHashMap<const Constraint*, ConstraintSnapshot> unsolvedConstraints{nullptr};
|
2022-09-08 23:14:25 +01:00
|
|
|
ScopeSnapshot rootScope;
|
2023-02-24 21:49:38 +00:00
|
|
|
DenseHashMap<const void*, std::string> typeStrings{nullptr};
|
2022-09-08 23:14:25 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
struct StepSnapshot
|
|
|
|
{
|
2023-02-24 21:49:38 +00:00
|
|
|
const Constraint* currentConstraint;
|
2022-09-08 23:14:25 +01:00
|
|
|
bool forced;
|
2023-02-24 21:49:38 +00:00
|
|
|
DenseHashMap<const Constraint*, ConstraintSnapshot> unsolvedConstraints{nullptr};
|
2022-09-08 23:14:25 +01:00
|
|
|
ScopeSnapshot rootScope;
|
2023-02-24 21:49:38 +00:00
|
|
|
DenseHashMap<const void*, std::string> typeStrings{nullptr};
|
2022-09-08 23:14:25 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
struct TypeSolveLog
|
|
|
|
{
|
|
|
|
BoundarySnapshot initialState;
|
|
|
|
std::vector<StepSnapshot> stepStates;
|
|
|
|
BoundarySnapshot finalState;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TypeCheckLog
|
|
|
|
{
|
|
|
|
std::vector<ErrorSnapshot> errors;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct DcrLogger
|
|
|
|
{
|
|
|
|
std::string compileOutput();
|
|
|
|
|
|
|
|
void captureSource(std::string source);
|
|
|
|
void captureGenerationError(const TypeError& error);
|
|
|
|
void captureConstraintLocation(NotNull<const Constraint> constraint, Location location);
|
2023-02-24 21:49:38 +00:00
|
|
|
void captureGenerationModule(const ModulePtr& module);
|
2022-09-08 23:14:25 +01:00
|
|
|
|
|
|
|
void pushBlock(NotNull<const Constraint> constraint, TypeId block);
|
|
|
|
void pushBlock(NotNull<const Constraint> constraint, TypePackId block);
|
|
|
|
void pushBlock(NotNull<const Constraint> constraint, NotNull<const Constraint> block);
|
|
|
|
void popBlock(TypeId block);
|
|
|
|
void popBlock(TypePackId block);
|
|
|
|
void popBlock(NotNull<const Constraint> block);
|
|
|
|
|
|
|
|
void captureInitialSolverState(const Scope* rootScope, const std::vector<NotNull<const Constraint>>& unsolvedConstraints);
|
2022-10-14 20:48:41 +01:00
|
|
|
StepSnapshot prepareStepSnapshot(
|
2024-08-02 15:30:04 +01:00
|
|
|
const Scope* rootScope,
|
|
|
|
NotNull<const Constraint> current,
|
|
|
|
bool force,
|
|
|
|
const std::vector<NotNull<const Constraint>>& unsolvedConstraints
|
|
|
|
);
|
2022-09-08 23:14:25 +01:00
|
|
|
void commitStepSnapshot(StepSnapshot snapshot);
|
|
|
|
void captureFinalSolverState(const Scope* rootScope, const std::vector<NotNull<const Constraint>>& unsolvedConstraints);
|
|
|
|
|
|
|
|
void captureTypeCheckError(const TypeError& error);
|
2022-10-14 20:48:41 +01:00
|
|
|
|
2022-09-08 23:14:25 +01:00
|
|
|
private:
|
|
|
|
ConstraintGenerationLog generationLog;
|
|
|
|
std::unordered_map<NotNull<const Constraint>, std::vector<ConstraintBlockTarget>> constraintBlocks;
|
|
|
|
TypeSolveLog solveLog;
|
|
|
|
TypeCheckLog checkLog;
|
|
|
|
|
2023-02-24 21:49:38 +00:00
|
|
|
ToStringOptions opts{true};
|
2022-09-08 23:14:25 +01:00
|
|
|
|
|
|
|
std::vector<ConstraintBlock> snapshotBlocks(NotNull<const Constraint> constraint);
|
2023-02-24 21:49:38 +00:00
|
|
|
void captureBoundaryState(BoundarySnapshot& target, const Scope* rootScope, const std::vector<NotNull<const Constraint>>& unsolvedConstraints);
|
2022-09-08 23:14:25 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace Luau
|