forked from chipsalliance/verible
-
Notifications
You must be signed in to change notification settings - Fork 0
/
verilog_linter_configuration.h
245 lines (200 loc) · 8.96 KB
/
verilog_linter_configuration.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VERIBLE_VERILOG_ANALYSIS_VERILOG_LINTER_CONFIGURATION_H_
#define VERIBLE_VERILOG_ANALYSIS_VERILOG_LINTER_CONFIGURATION_H_
#include <iosfwd>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "common/analysis/line_lint_rule.h"
#include "common/analysis/syntax_tree_lint_rule.h"
#include "common/analysis/text_structure_lint_rule.h"
#include "common/analysis/token_stream_lint_rule.h"
#include "verilog/analysis/lint_rule_registry.h"
namespace verilog {
// Setting for a configuration
struct RuleSetting {
bool enabled;
std::string configuration;
};
// Enum denoting a ruleset
// kNone no rules are enabled
// kDefault default ruleset is enabled
// kAll all rules are enabled
enum class RuleSet { kNone, kDefault, kAll };
// Pair of functions that perform stringification and destringification
// in order to support commandline flags.
//
// AbslUnparseFlag takes the parsed representation of a ruleset
// and converts it into string representation.
std::string AbslUnparseFlag(const RuleSet& rules);
// ParseFlags takes a source string text and a target Ruleset.
// It attempts to parse text into a RuleSet and put that RuleSet into rules
// If successful, returns true.
// Otherwise, sets string error to the a error message and returns false.
bool AbslParseFlag(absl::string_view text, RuleSet* rules, std::string* error);
// Container class for parse/unparse flags
// Keys must be the exact string_views in registered maps (not just string
// equivalent) for the lifetime guarantee.
struct RuleBundle {
std::map<absl::string_view, RuleSetting> rules;
// Parse configuration from input. Separator between rules is 'separator',
// typically that would be a comma or newline.
bool ParseConfiguration(absl::string_view text, char separator,
std::string* error);
std::string UnparseConfiguration(char separator) const;
};
// Pair of functions that perform stringification and destringification
// in order to support commandline flags.
//
// AbslUnparseFlag takes the parsed representation of a flag (RuleBundle)
// and converts it into string representation.
std::string AbslUnparseFlag(const RuleBundle& bundle);
// ParseFlags takes a source string text and a target RuleBundle.
// It clears bundle and parses text into it by checking to make sure
// each rule is registered with the LintRuleRegistry.
// If a rule is prepended with '-', then it is mapped to RuleSetting::kRuleOff
// Otherwise, it is mapped to RuleSetting::kRuleOn
// If all rules are parsed successfully, returns true.
// Otherwise, sets string error to the a error message containing the
// invalid lint rule and returns false.
bool AbslParseFlag(absl::string_view text, RuleBundle* bundle,
std::string* error);
// ProjectPolicy is needed in a transitional period when new rules are
// becoming enabled while pre-existing code is still following their
// respective project conventions and guidelines. These blanket waivers
// are intended to minimize agony on current projects, while allowing
// the full set of rules to take effect on new projects.
struct ProjectPolicy {
// A short name for policy, for diagnostic purposes.
absl::string_view name;
// Raw string to check for being part of the path. Not a regex pattern.
// Apply this exemption only if substring occurs in the file path.
std::vector<const char*> path_substrings;
// Raw string to check for being part of the path. Not a regex pattern.
// Files that match the exclusion will not be analyzed.
// This is suitable for paths that contain files that no human will ever
// read.
std::vector<const char*> path_exclusions;
// Reviewers to involve for policy changes. At least two.
std::vector<const char*> owners;
// Names of lint rules to disable.
std::vector<const char*> disabled_rules;
// Names of lint rules to enable (takes precedence over disabled_rules).
std::vector<const char*> enabled_rules;
// Returns a path if filename matches any of path_substrings,
// otherwise nullptr.
const char* MatchesAnyPath(absl::string_view filename) const;
// Returns a path if filename matches any of path_exclusions,
// otherwise nullptr.
const char* MatchesAnyExclusions(absl::string_view filename) const;
// Returns true if all disabled_rules and enabled_rules refer to registered
// rules. This helps catch typos.
bool IsValid() const;
// Returns a glob pattern for shell case statement: "*path1* | *path2* | ..."
std::string ListPathGlobs() const;
};
struct LinterOptions {
// strings, ints, bools, and unprocessed values from flags, no other derived
// information. Reasonable default values may be specified here for each
// member
// The base set of rules used by linter
const RuleSet ruleset;
// Bundle of rules to enable/disable in addition to the base set
const RuleBundle& rules;
// Path to a file with extra linter configuration, applied on top of the
// base 'ruleset' and extra 'rules'
std::string config_file;
// Enables upward config file search
bool rules_config_search;
// Defines the starting point for the upward config search algorithm,
// usually set to the currently linted file
std::string linting_start_file;
// Path to the external waivers configuration file
std::string waiver_files;
};
// LinterConfiguration is used for tracking enabled lint rules
// Individual LintRules are defined LintRuleRegistry. Their names are the
// strings that they are registered under.
//
// Usage
// LinterConfiguration config;
// config.UseRuleSet(RuleSet::kDefault);
// config.TurnOn("rule-1");
// config.TurnOn("rule-2");
// linter.Configure(config);
//
class LinterConfiguration {
public:
// Constructor has no rules enabled by default;
LinterConfiguration() {}
// This is copy-able.
LinterConfiguration(const LinterConfiguration&) = default;
void TurnOn(const analysis::LintRuleId& rule) {
configuration_[rule] = {true, ""};
}
void TurnOff(const analysis::LintRuleId& rule) {
configuration_[rule] = {false, ""};
}
bool RuleIsOn(const analysis::LintRuleId& rule) const;
// Clears configuration and updates to passed ruleset.
// Behavior is as follows:
// RuleSet::kAll Turns on all registered rules
// RuleSet::kNone Turns off all rules
// RuleSet::kDefault Turns on default set of rules as defined in
// analysis/default_rules.h
//
// Note that additional rules can be layered on top of a ruleset via
// TurnOn/TurnOff/UseRuleBundle.
void UseRuleSet(const RuleSet& rules);
// Updates LinterConfiguration to enabled/disable all lint rules
// in rule_bundle
void UseRuleBundle(const RuleBundle& rule_bundle);
// Adjust set of active rules based on the filename.
void UseProjectPolicy(const ProjectPolicy& policy,
absl::string_view filename);
// Return the keys of enabled lint rules, sorted.
std::set<analysis::LintRuleId> ActiveRuleIds() const;
// Creates instances of every enabled syntax tree rule
absl::StatusOr<std::vector<std::unique_ptr<verible::SyntaxTreeLintRule>>>
CreateSyntaxTreeRules() const;
// Creates instances of every enabled token stream rule
absl::StatusOr<std::vector<std::unique_ptr<verible::TokenStreamLintRule>>>
CreateTokenStreamRules() const;
// Creates instances of every enabled line rule
absl::StatusOr<std::vector<std::unique_ptr<verible::LineLintRule>>>
CreateLineRules() const;
// Creates instances of every enabled text structure lint rule
absl::StatusOr<std::vector<std::unique_ptr<verible::TextStructureLintRule>>>
CreateTextStructureRules() const;
// Path to external lint waivers configuration file
std::string external_waivers;
// Returns true if configurations are equivalent.
bool operator==(const LinterConfiguration&) const;
bool operator!=(const LinterConfiguration& r) const { return !(*this == r); }
// Appends linter rules configuration from a file
absl::Status AppendFromFile(absl::string_view filename);
// Generates configuration forn LinterOptions
absl::Status ConfigureFromOptions(const LinterOptions& options);
private:
// map of all enabled rules
std::map<analysis::LintRuleId, RuleSetting> configuration_;
};
std::ostream& operator<<(std::ostream&, const LinterConfiguration&);
} // namespace verilog
#endif // VERIBLE_VERILOG_ANALYSIS_VERILOG_LINTER_CONFIGURATION_H_