+/// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
+/// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`.
+fn arg_value<'a>(
+ args: impl IntoIterator<Item = &'a String>,
+ find_arg: &str,
+ pred: impl Fn(&str) -> bool,
+) -> Option<&'a str> {
+ let mut args = args.into_iter().map(String::as_str);
+
+ while let Some(arg) = args.next() {
+ let arg: Vec<_> = arg.splitn(2, '=').collect();
+ if arg.get(0) != Some(&find_arg) {
+ continue;
+ }
+
+ let value = arg.get(1).cloned().or_else(|| args.next());
+ if value.as_ref().map_or(false, |p| pred(p)) {
+ return value;
+ }
+ }
+ None
+}
+
+#[test]
+fn test_arg_value() {
+ let args: Vec<_> = ["--bar=bar", "--foobar", "123", "--foo"]
+ .iter()
+ .map(std::string::ToString::to_string)
+ .collect();
+
+ assert_eq!(arg_value(None, "--foobar", |_| true), None);
+ assert_eq!(arg_value(&args, "--bar", |_| false), None);
+ assert_eq!(arg_value(&args, "--bar", |_| true), Some("bar"));
+ assert_eq!(arg_value(&args, "--bar", |p| p == "bar"), Some("bar"));
+ assert_eq!(arg_value(&args, "--bar", |p| p == "foo"), None);
+ assert_eq!(arg_value(&args, "--foobar", |p| p == "foo"), None);
+ assert_eq!(arg_value(&args, "--foobar", |p| p == "123"), Some("123"));
+ assert_eq!(arg_value(&args, "--foo", |_| true), None);
+}
+
+#[allow(clippy::too_many_lines)]
+
+struct ClippyCallbacks;
+
+impl rustc_driver::Callbacks for ClippyCallbacks {
+ fn after_parsing(&mut self, compiler: &interface::Compiler) -> bool {
+ let sess = compiler.session();
+ let mut registry = rustc_plugin::registry::Registry::new(
+ sess,
+ compiler
+ .parse()
+ .expect(
+ "at this compilation stage \
+ the crate must be parsed",
+ )
+ .peek()
+ .span,
+ );
+ registry.args_hidden = Some(Vec::new());
+
+ let conf = clippy_lints::read_conf(®istry);
+ clippy_lints::register_plugins(&mut registry, &conf);
+
+ let rustc_plugin::registry::Registry {
+ early_lint_passes,
+ late_lint_passes,
+ lint_groups,
+ llvm_passes,
+ attributes,
+ ..
+ } = registry;
+ let mut ls = sess.lint_store.borrow_mut();
+ for pass in early_lint_passes {
+ ls.register_early_pass(Some(sess), true, false, pass);
+ }
+ for pass in late_lint_passes {
+ ls.register_late_pass(Some(sess), true, false, false, pass);
+ }
+
+ for (name, (to, deprecated_name)) in lint_groups {
+ ls.register_group(Some(sess), true, name, deprecated_name, to);
+ }
+ clippy_lints::register_pre_expansion_lints(sess, &mut ls, &conf);
+ clippy_lints::register_renamed(&mut ls);
+
+ sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
+ sess.plugin_attributes.borrow_mut().extend(attributes);
+
+ // Continue execution
+ true
+ }
+}
+