[torque] Refactor annotation handling
This CL introduces an AnnotationSet to unify annotation handling. Grammar rules now accept a list of annotations (via annotations Symbol), where an annotation is an Identifier starting with '@'. The new class AnnotationSet can be used to restrict the allowed annotations and query presence of annotations in the Make* functions. Bug: v8:7793 Change-Id: Iad5435d4a94a3bea99aca76c23d2cffffe78a97f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1601142 Commit-Queue: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Simon Zünd <szuend@chromium.org> Cr-Commit-Position: refs/heads/master@{#61334}
This commit is contained in:
parent
ed833ff5f0
commit
ad010efaa4
@ -208,6 +208,12 @@ struct Identifier : AstNode {
|
||||
std::string value;
|
||||
};
|
||||
|
||||
struct IdentifierPtrValueEq {
|
||||
bool operator()(const Identifier* a, const Identifier* b) {
|
||||
return a->value < b->value;
|
||||
}
|
||||
};
|
||||
|
||||
struct IdentifierExpression : LocationExpression {
|
||||
DEFINE_AST_NODE_LEAF_BOILERPLATE(IdentifierExpression)
|
||||
IdentifierExpression(SourcePosition pos,
|
||||
|
@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <cctype>
|
||||
#include <set>
|
||||
|
||||
#include "src/torque/constants.h"
|
||||
#include "src/torque/earley-parser.h"
|
||||
@ -604,9 +605,35 @@ base::Optional<ParseResult> MakeMethodDeclaration(
|
||||
return ParseResult{result};
|
||||
}
|
||||
|
||||
class AnnotationSet {
|
||||
public:
|
||||
AnnotationSet(ParseResultIterator* iter,
|
||||
const std::set<std::string>& allowed) {
|
||||
auto list = iter->NextAs<std::vector<Identifier*>>();
|
||||
for (const Identifier* i : list) {
|
||||
if (allowed.find(i->value) == allowed.end()) {
|
||||
std::stringstream s;
|
||||
s << "Annotation " << i->value << " is not allowed here";
|
||||
ReportLintError(s.str(), i->pos);
|
||||
}
|
||||
if (!set_.insert(i->value).second) {
|
||||
std::stringstream s;
|
||||
s << "Duplicate annotation " << i->value;
|
||||
ReportLintError(s.str(), i->pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Contains(const std::string& s) { return set_.find(s) != set_.end(); }
|
||||
|
||||
private:
|
||||
std::set<std::string> set_;
|
||||
};
|
||||
|
||||
base::Optional<ParseResult> MakeClassDeclaration(
|
||||
ParseResultIterator* child_results) {
|
||||
auto generate_print = child_results->NextAs<bool>();
|
||||
AnnotationSet annotations(child_results, {"@generatePrint"});
|
||||
bool generate_print = annotations.Contains("@generatePrint");
|
||||
auto is_extern = child_results->NextAs<bool>();
|
||||
auto transient = child_results->NextAs<bool>();
|
||||
auto name = child_results->NextAs<Identifier*>();
|
||||
@ -1242,12 +1269,18 @@ struct TorqueGrammar : Grammar {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool MatchAnnotation(InputPosition* pos) {
|
||||
InputPosition current = *pos;
|
||||
if (!MatchString("@", ¤t)) return false;
|
||||
if (!MatchIdentifier(¤t)) return false;
|
||||
*pos = current;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool MatchIntrinsicName(InputPosition* pos) {
|
||||
InputPosition current = *pos;
|
||||
if (!MatchString("%", ¤t)) return false;
|
||||
if (!MatchChar(std::isalpha, ¤t)) return false;
|
||||
while (MatchChar(std::isalnum, ¤t) || MatchString("_", pos)) {
|
||||
}
|
||||
if (!MatchIdentifier(¤t)) return false;
|
||||
*pos = current;
|
||||
return true;
|
||||
}
|
||||
@ -1318,6 +1351,13 @@ struct TorqueGrammar : Grammar {
|
||||
// Result: Identifier*
|
||||
Symbol name = {Rule({&identifier}, MakeIdentifier)};
|
||||
|
||||
// Result: Identifier*
|
||||
Symbol annotation = {
|
||||
Rule({Pattern(MatchAnnotation)}, MakeIdentifierFromMatchedInput)};
|
||||
|
||||
// Result: std::vector<Identifier*>
|
||||
Symbol* annotations = List<Identifier*>(&annotation);
|
||||
|
||||
// Result: std::string
|
||||
Symbol intrinsicName = {
|
||||
Rule({Pattern(MatchIntrinsicName)}, YieldMatchedInput)};
|
||||
@ -1696,8 +1736,8 @@ struct TorqueGrammar : Grammar {
|
||||
Rule({Token("const"), &name, Token(":"), &type, Token("generates"),
|
||||
&externalString, Token(";")},
|
||||
AsSingletonVector<Declaration*, MakeExternConstDeclaration>()),
|
||||
Rule({CheckIf(Token("@generatePrint")), CheckIf(Token("extern")),
|
||||
CheckIf(Token("transient")), Token("class"), &name,
|
||||
Rule({annotations, CheckIf(Token("extern")), CheckIf(Token("transient")),
|
||||
Token("class"), &name,
|
||||
Optional<TypeExpression*>(Sequence({Token("extends"), &type})),
|
||||
Optional<std::string>(
|
||||
Sequence({Token("generates"), &externalString})),
|
||||
|
@ -131,8 +131,8 @@ std::string CurrentPositionAsString() {
|
||||
throw error;
|
||||
}
|
||||
|
||||
void ReportLintError(const std::string& error) {
|
||||
LintErrors::Get().push_back({error, CurrentSourcePosition::Get()});
|
||||
void ReportLintError(const std::string& error, SourcePosition pos) {
|
||||
LintErrors::Get().push_back({error, pos});
|
||||
}
|
||||
|
||||
void NamingConventionError(const std::string& type, const std::string& name,
|
||||
|
@ -34,7 +34,8 @@ struct LintError {
|
||||
};
|
||||
DECLARE_CONTEXTUAL_VARIABLE(LintErrors, std::vector<LintError>);
|
||||
|
||||
void ReportLintError(const std::string& error);
|
||||
void ReportLintError(const std::string& error,
|
||||
SourcePosition pos = CurrentSourcePosition::Get());
|
||||
|
||||
// Prints a LintError with the format "{type} '{name}' doesn't follow
|
||||
// '{convention}' naming convention".
|
||||
|
Loading…
Reference in New Issue
Block a user