// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details #include "Luau/IostreamHelpers.h" #include "Luau/ToString.h" namespace Luau { std::ostream& operator<<(std::ostream& stream, const Position& position) { return stream << "{ line = " << position.line << ", col = " << position.column << " }"; } std::ostream& operator<<(std::ostream& stream, const Location& location) { return stream << "Location { " << location.begin << ", " << location.end << " }"; } std::ostream& operator<<(std::ostream& stream, const AstName& name) { if (name.value) return stream << name.value; else return stream << ""; } template static void errorToString(std::ostream& stream, const T& err) { if constexpr (false) { } else if constexpr (std::is_same_v) stream << "TypeMismatch { " << toString(err.wantedType) << ", " << toString(err.givenType) << " }"; else if constexpr (std::is_same_v) stream << "UnknownSymbol { " << err.name << " , context " << err.context << " }"; else if constexpr (std::is_same_v) stream << "UnknownProperty { " << toString(err.table) << ", key = " << err.key << " }"; else if constexpr (std::is_same_v) stream << "NotATable { " << toString(err.ty) << " }"; else if constexpr (std::is_same_v) stream << "CannotExtendTable { " << toString(err.tableType) << ", context " << err.context << ", prop \"" << err.prop << "\" }"; else if constexpr (std::is_same_v) stream << "OnlyTablesCanHaveMethods { " << toString(err.tableType) << " }"; else if constexpr (std::is_same_v) stream << "DuplicateTypeDefinition { " << err.name << " }"; else if constexpr (std::is_same_v) stream << "CountMismatch { expected " << err.expected << ", got " << err.actual << ", context " << err.context << " }"; else if constexpr (std::is_same_v) stream << "FunctionDoesNotTakeSelf { }"; else if constexpr (std::is_same_v) stream << "FunctionRequiresSelf { }"; else if constexpr (std::is_same_v) stream << "OccursCheckFailed { }"; else if constexpr (std::is_same_v) stream << "UnknownRequire { " << err.modulePath << " }"; else if constexpr (std::is_same_v) { stream << "IncorrectGenericParameterCount { name = " << err.name; if (!err.typeFun.typeParams.empty() || !err.typeFun.typePackParams.empty()) { stream << "<"; bool first = true; for (auto param : err.typeFun.typeParams) { if (first) first = false; else stream << ", "; stream << toString(param.ty); } for (auto param : err.typeFun.typePackParams) { if (first) first = false; else stream << ", "; stream << toString(param.tp); } stream << ">"; } stream << ", typeFun = " << toString(err.typeFun.type) << ", actualCount = " << err.actualParameters << " }"; } else if constexpr (std::is_same_v) stream << "SyntaxError { " << err.message << " }"; else if constexpr (std::is_same_v) stream << "CodeTooComplex {}"; else if constexpr (std::is_same_v) stream << "UnificationTooComplex {}"; else if constexpr (std::is_same_v) { stream << "UnknownPropButFoundLikeProp { key = '" << err.key << "', suggested = { "; bool first = true; for (Name name : err.candidates) { if (first) first = false; else stream << ", "; stream << "'" << name << "'"; } stream << " }, table = " << toString(err.table) << " } "; } else if constexpr (std::is_same_v) stream << "GenericError { " << err.message << " }"; else if constexpr (std::is_same_v) stream << "InternalError { " << err.message << " }"; else if constexpr (std::is_same_v) stream << "CannotCallNonFunction { " << toString(err.ty) << " }"; else if constexpr (std::is_same_v) stream << "ExtraInformation { " << err.message << " }"; else if constexpr (std::is_same_v) stream << "DeprecatedApiUsed { " << err.symbol << ", useInstead = " << err.useInstead << " }"; else if constexpr (std::is_same_v) { stream << "ModuleHasCyclicDependency {"; bool first = true; for (const ModuleName& name : err.cycle) { if (first) first = false; else stream << ", "; stream << name; } stream << "}"; } else if constexpr (std::is_same_v) stream << "IllegalRequire { " << err.moduleName << ", reason = " << err.reason << " }"; else if constexpr (std::is_same_v) stream << "FunctionExitsWithoutReturning {" << toString(err.expectedReturnType) << "}"; else if constexpr (std::is_same_v) stream << "DuplicateGenericParameter { " + err.parameterName + " }"; else if constexpr (std::is_same_v) stream << "CannotInferBinaryOperation { op = " + toString(err.op) + ", suggested = '" + (err.suggestedToAnnotate ? *err.suggestedToAnnotate : "") + "', kind " << err.kind << "}"; else if constexpr (std::is_same_v) { stream << "MissingProperties { superType = '" << toString(err.superType) << "', subType = '" << toString(err.subType) << "', properties = { "; bool first = true; for (Name name : err.properties) { if (first) first = false; else stream << ", "; stream << "'" << name << "'"; } stream << " }, context " << err.context << " } "; } else if constexpr (std::is_same_v) stream << "SwappedGenericTypeParameter { name = '" + err.name + "', kind = " + std::to_string(err.kind) + " }"; else if constexpr (std::is_same_v) stream << "OptionalValueAccess { optional = '" + toString(err.optional) + "' }"; else if constexpr (std::is_same_v) { stream << "MissingUnionProperty { type = '" + toString(err.type) + "', missing = { "; bool first = true; for (auto ty : err.missing) { if (first) first = false; else stream << ", "; stream << "'" << toString(ty) << "'"; } stream << " }, key = '" + err.key + "' }"; } else if constexpr (std::is_same_v) stream << "TypesAreUnrelated { left = '" + toString(err.left) + "', right = '" + toString(err.right) + "' }"; else if constexpr (std::is_same_v) stream << "NormalizationTooComplex { }"; else static_assert(always_false_v, "Non-exhaustive type switch"); } std::ostream& operator<<(std::ostream& stream, const TypeErrorData& data) { auto cb = [&](const auto& e) { return errorToString(stream, e); }; visit(cb, data); return stream; } std::ostream& operator<<(std::ostream& stream, const TypeError& error) { return stream << "TypeError { \"" << error.moduleName << "\", " << error.location << ", " << error.data << " }"; } std::ostream& operator<<(std::ostream& stream, const TableState& tv) { return stream << static_cast::type>(tv); } std::ostream& operator<<(std::ostream& stream, const TypeVar& tv) { return stream << toString(tv); } std::ostream& operator<<(std::ostream& stream, const TypePackVar& tv) { return stream << toString(tv); } } // namespace Luau