-
-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
365 additions
and
196 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/// Diagnostic.h, diagnostic types and definitions | ||
/// | ||
/// Diagnostics are structures with a main message, | ||
/// and optionally some additional information (body). | ||
/// | ||
/// For diagnostics with a body, | ||
/// they may need a special overrided function to format the message. | ||
/// | ||
#pragma once | ||
|
||
#include "Range.h" | ||
#include <optional> | ||
#include <string> | ||
|
||
namespace nixd { | ||
|
||
/// The super class for all diagnostics. | ||
/// concret diagnostic types are defined in Diagnostic*.inc | ||
struct Diagnostic { | ||
|
||
/// Location of this diagnostic | ||
RangeIdx Range; | ||
|
||
Diagnostic(RangeIdx Range) : Range(Range) {} | ||
|
||
/// Each diagnostic contains a severity field, | ||
/// should be "Fatal", "Error" or "Warning" | ||
/// this will affect the eval process. | ||
/// | ||
/// "Fatal" -- shouldn't eval the code, e.g. parsing error. | ||
/// "Error" -- trigger an error in nix, but we can eval the code. | ||
/// "Warning" -- just a warning. | ||
/// "Note" -- some additional information about the error. | ||
enum Severity { DS_Fatal, DS_Error, DS_Warning, DS_Note }; | ||
|
||
/// Internal diagnostic kind | ||
enum Kind { | ||
#define DIAG_ALL(SNAME, CNAME, SEVERITY, MESSAGE) DK_##CNAME, | ||
#include "DiagnosticMerge.inc" | ||
#undef DIAG_ALL | ||
}; | ||
|
||
[[nodiscard]] virtual Kind kind() const = 0; | ||
|
||
[[nodiscard]] virtual Severity severity() const = 0; | ||
|
||
/// Format a printable diagnostic | ||
[[nodiscard]] virtual std::string_view format() const = 0; | ||
|
||
/// Short name, switch name. | ||
/// There might be a human readable short name that controls the diagnostic | ||
/// For example, one may pass -Wno-dup-formal to suppress duplicated formals. | ||
/// A special case for parsing errors, generated from bison | ||
/// have the sname "bison" | ||
[[nodiscard]] virtual const char *sname() const = 0; | ||
|
||
virtual ~Diagnostic() = default; | ||
}; | ||
|
||
struct NotableDiagnostic : Diagnostic { | ||
NotableDiagnostic(RangeIdx Range) : Diagnostic(Range) {} | ||
using NotesTy = std::vector<std::unique_ptr<Diagnostic>>; | ||
NotesTy Notes; | ||
NotesTy ¬es() { return Notes; } | ||
}; | ||
|
||
#define DIAG_SIMPLE(SNAME, CNAME, SEVERITY, MESSAGE) \ | ||
struct Diag##CNAME : Diagnostic { \ | ||
Diag##CNAME(RangeIdx Range) : Diagnostic(Range) {} \ | ||
std::string_view format() const override { return MESSAGE; } \ | ||
const char *sname() const override { return SNAME; } \ | ||
Severity severity() const override { return DS_##SEVERITY; } \ | ||
Kind kind() const override { return DK_##CNAME; } \ | ||
}; | ||
#include "DiagnosticKinds.inc" | ||
#undef DIAG_SIMPLE | ||
|
||
#define DIAG_NOTE(SNAME, CNAME, SEVERITY, MESSAGE) \ | ||
struct Diag##CNAME : NotableDiagnostic { \ | ||
Diag##CNAME(RangeIdx Range) : NotableDiagnostic(Range) {} \ | ||
std::string_view format() const override { return MESSAGE; } \ | ||
const char *sname() const override { return SNAME; } \ | ||
Severity severity() const override { return DS_##SEVERITY; } \ | ||
Kind kind() const override { return DK_##CNAME; } \ | ||
}; | ||
#include "DiagnosticKinds.inc" | ||
#undef DIAG_NOTE | ||
|
||
#define DIAG_BODY(SNAME, CNAME, SEVERITY, MESSAGE, BODY) \ | ||
struct Diag##CNAME : Diagnostic BODY; | ||
#include "DiagnosticKinds.inc" | ||
#undef DIAG_BODY | ||
|
||
#define DIAG_NOTE_BODY(SNAME, CNAME, SEVERITY, MESSAGE, BODY) \ | ||
struct Diag##CNAME : NotableDiagnostic BODY; | ||
#include "DiagnosticKinds.inc" | ||
#undef DIAG_NOTE_BODY | ||
|
||
} // namespace nixd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/// DiagnosticKinds.inc, diagnostic declarations | ||
|
||
// provides: DIAG_SIMPLE(SNAME, CNAME, SEVERITY, MESSAGE) | ||
// provides: DIAG_BODY(SNAME, CNAME, SEVERITY, MESSAGE, BODY) | ||
// provides: DIAG_NOTE(SNAME, CNAME, SEVERITY, MESSAGE) | ||
// provides: DIAG_NOTE_BODY(SNAME, CNAME, SEVERITY, MESSAGE, BODY) | ||
|
||
//=============================================================================/ | ||
// DIAG_SIMPLE(SName, ClassName, Severity, Message) | ||
// "simple" means they have no additional body | ||
//=============================================================================/ | ||
|
||
#ifdef DIAG_SIMPLE | ||
DIAG_SIMPLE("note-prev", PrevDeclared, Note, "previously declared here") | ||
DIAG_SIMPLE("let-dynamic", LetDynamic, Error, | ||
"dynamic attributes are not allowed in let ... in ... expression") | ||
DIAG_SIMPLE("inherit-dynamic", InheritDynamic, Error, | ||
"dynamic attributes are not allowed in inherit") | ||
DIAG_SIMPLE("empty-inherit", EmptyInherit, Warning, "empty inherit expression") | ||
DIAG_SIMPLE("or-identifier", OrIdentifier, Warning, | ||
"keyword `or` used as an identifier") | ||
DIAG_SIMPLE("deprecated-url-literal", DeprecatedURL, Warning, | ||
"URL literal is deprecated") | ||
DIAG_SIMPLE("deprecated-let", DeprecatedLet, Warning, | ||
"using deprecated `let' syntactic sugar `let {..., body = ...}' -> " | ||
"(rec {..., body = ...}).body'") | ||
DIAG_SIMPLE("path-trailing-slash", PathTrailingSlash, Fatal, | ||
"path has a trailing slash") | ||
#endif // DIAG_SIMPLE | ||
|
||
//=============================================================================/ | ||
// DIAG_NOTE(SName, ClassName, Severity, Message) | ||
// "simple", but with additional note support | ||
//=============================================================================/ | ||
#ifdef DIAG_NOTE | ||
DIAG_NOTE("dup-formal", DuplicatedFormal, Error, | ||
"duplicated function formal declaration") | ||
DIAG_NOTE("dup-formal-arg", DuplicatedFormalToArg, Error, | ||
"function argument duplicated to a function formal") | ||
DIAG_NOTE("merge-diff-rec", MergeDiffRec, Warning, | ||
"merging two attributes with different `rec` modifiers, the latter " | ||
"will be implicitly ignored") | ||
#endif // DIAG_NOTE | ||
|
||
#define COMMON_METHOD \ | ||
Severity severity() const override; \ | ||
Kind kind() const override; \ | ||
std::string_view format() const override; \ | ||
const char *sname() const override; \ | ||
static constexpr const char *message(); | ||
|
||
//=============================================================================/ | ||
// DIAG_BODY(SName, ClassName, Severity, Message, Body) | ||
// diagnostics with special body | ||
//=============================================================================/ | ||
#ifdef DIAG_BODY | ||
DIAG_BODY("bison", BisonParse, Fatal, "{0}", { | ||
DiagBisonParse(RangeIdx Range, std::string Str); | ||
std::string Str; | ||
COMMON_METHOD | ||
}) | ||
DIAG_BODY("merge-diff-rec-this-rec", ThisRecursive, Note, | ||
"this attribute set is {0}recursive", { | ||
DiagThisRecursive(RangeIdx Range, bool Recursive); | ||
std::string Str; | ||
COMMON_METHOD | ||
}) | ||
DIAG_BODY("merge-diff-rec-consider", RecConsider, Note, | ||
"while this attribute set is marked as {0}recursive, it " | ||
"will be considered as {1}recursive", | ||
{ | ||
DiagRecConsider(RangeIdx Range, bool MarkedRecursive); | ||
std::string Str; | ||
COMMON_METHOD | ||
}) | ||
DIAG_BODY("invalid-float", InvalidFloat, Note, "invalid float {0}", { | ||
DiagInvalidFloat(RangeIdx Range, std::string_view Content); | ||
std::string Str; | ||
COMMON_METHOD | ||
}) | ||
DIAG_BODY("invalid-integer", InvalidInteger, Note, "invalid integer {0}", { | ||
DiagInvalidInteger(RangeIdx Range, std::string_view Content); | ||
std::string Str; | ||
COMMON_METHOD | ||
}) | ||
#endif // DIAG_BODY | ||
|
||
//=============================================================================/ | ||
// DIAG_NOTE_BODY(SName, ClassName, Severity, Message, Body) | ||
// diagnostics with special body, but with additional note support | ||
//=============================================================================/ | ||
#ifdef DIAG_NOTE_BODY | ||
DIAG_NOTE_BODY("dup-formal-arg", DuplicatedAttr, Error, "duplicated attr `{0}`", | ||
{ | ||
DiagDuplicatedAttr(RangeIdx Range, std::string AttrName); | ||
std::string Str; | ||
COMMON_METHOD | ||
}) | ||
#endif // DIAG_NOTE_BODY | ||
|
||
#undef COMMON_METHOD |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// DiagnosticMerge.inc, merge all declarations | ||
|
||
// provides: DIAG_ALL(SNAME, CNAME, SEVERITY, MESSAGE) | ||
|
||
#ifdef DIAG_ALL | ||
|
||
#define DIAG_SIMPLE(SNAME, CNAME, SEVERITY, MESSAGE) \ | ||
DIAG_ALL(SNAME, CNAME, SEVERITY, MESSAGE) | ||
#define DIAG_BODY(SNAME, CNAME, SEVERITY, MESSAGE, BODY) \ | ||
DIAG_ALL(SNAME, CNAME, SEVERITY, MESSAGE) | ||
#define DIAG_NOTE_BODY(SNAME, CNAME, SEVERITY, MESSAGE, BODY) \ | ||
DIAG_ALL(SNAME, CNAME, SEVERITY, MESSAGE) | ||
#define DIAG_NOTE(SNAME, CNAME, SEVERITY, MESSAGE) \ | ||
DIAG_ALL(SNAME, CNAME, SEVERITY, MESSAGE) | ||
|
||
#include "DiagnosticKinds.inc" | ||
|
||
#undef DIAG_NOTE | ||
#undef DIAG_NOTE_BODY | ||
#undef DIAG_BODY | ||
#undef DIAG_SIMPLE | ||
|
||
#endif |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#include "nixd/Basic/Diagnostic.h" | ||
#include "nixd/Basic/Range.h" | ||
|
||
#include "llvm/Support/FormatVariadic.h" | ||
|
||
namespace nixd { | ||
|
||
#define DIAG_BODY(SNAME, CNAME, SEVERITY, MESSAGE, BODY) \ | ||
const char *Diag##CNAME::sname() const { return SNAME; } \ | ||
Diagnostic::Severity Diag##CNAME::severity() const { return DS_##SEVERITY; } \ | ||
Diagnostic::Kind Diag##CNAME::kind() const { return DK_##CNAME; } \ | ||
constexpr const char *Diag##CNAME::message() { return MESSAGE; } \ | ||
std::string_view Diag##CNAME::format() const { return Str; } | ||
#define DIAG_NOTE_BODY(SNAME, CNAME, SEVERITY, MESSAGE, BODY) \ | ||
DIAG_BODY(SNAME, CNAME, SEVERITY, MESSAGE, BODY) | ||
#include "nixd/Basic/DiagnosticKinds.inc" | ||
#undef DIAG_BODY | ||
#undef DIAG_NOTE_BODY | ||
|
||
DiagBisonParse::DiagBisonParse(RangeIdx Range, std::string Str) | ||
: Diagnostic(Range), Str(std::move(Str)) {} | ||
|
||
DiagDuplicatedAttr::DiagDuplicatedAttr(RangeIdx Range, std::string AttrName) | ||
: NotableDiagnostic(Range) { | ||
Str = llvm::formatv(message(), AttrName); | ||
} | ||
|
||
static const char *getPrefix(bool P) { return P ? "" : "non-"; } | ||
|
||
DiagThisRecursive::DiagThisRecursive(RangeIdx Range, bool Recursive) | ||
: Diagnostic(Range) { | ||
Str = llvm::formatv(message(), getPrefix(Recursive)); | ||
} | ||
|
||
DiagRecConsider::DiagRecConsider(RangeIdx Range, bool MarkedRecursive) | ||
: Diagnostic(Range) { | ||
Str = llvm::formatv(message(), getPrefix(MarkedRecursive), | ||
getPrefix(!MarkedRecursive)); | ||
} | ||
|
||
DiagInvalidInteger::DiagInvalidInteger(RangeIdx Range, std::string_view Content) | ||
: Diagnostic(Range) { | ||
Str = llvm::formatv(message(), Content); | ||
} | ||
|
||
DiagInvalidFloat::DiagInvalidFloat(RangeIdx Range, | ||
const std::string_view Content) | ||
: Diagnostic(Range) { | ||
Str = llvm::formatv(message(), Content); | ||
} | ||
|
||
} // namespace nixd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
libnixdBasicDeps = [ nix_all, llvm ] | ||
libnixdBasic = library('nixdBasic' | ||
, [ 'Diagnostic.cpp' | ||
] | ||
, include_directories: nixd_inc | ||
, dependencies: libnixdBasicDeps | ||
, install: true | ||
) | ||
|
||
nixdBasic = declare_dependency( include_directories: nixd_inc | ||
, dependencies: libnixdBasicDeps | ||
, link_with: libnixdBasic | ||
) |
Oops, something went wrong.