]> git.lizzy.rs Git - rust.git/blobdiff - src/attr.rs
Update rustc-ap-* crates to 606.0.0 (#3835)
[rust.git] / src / attr.rs
index d7d1876b02d72e0c85363a98aa02e7792d45d3f4..63a01e5660380217b3867bd0c6ac0bfe463d2251 100644 (file)
@@ -1,32 +1,26 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 //! Format attributes and meta items.
 
-use comment::{contains_comment, rewrite_doc_comment, CommentStyle};
-use config::lists::*;
-use config::IndentStyle;
-use expr::rewrite_literal;
-use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
-use overflow;
-use rewrite::{Rewrite, RewriteContext};
-use shape::Shape;
-use types::{rewrite_path, PathContext};
-use utils::{count_newlines, mk_sp};
-
 use syntax::ast;
 use syntax::source_map::{BytePos, Span, DUMMY_SP};
+use syntax::symbol::sym;
+
+use self::doc_comment::DocCommentFormatter;
+use crate::comment::{contains_comment, rewrite_doc_comment, CommentStyle};
+use crate::config::lists::*;
+use crate::config::IndentStyle;
+use crate::expr::rewrite_literal;
+use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
+use crate::overflow;
+use crate::rewrite::{Rewrite, RewriteContext};
+use crate::shape::Shape;
+use crate::types::{rewrite_path, PathContext};
+use crate::utils::{count_newlines, mk_sp};
+
+mod doc_comment;
 
 /// Returns attributes on the given statement.
-pub fn get_attrs_from_stmt(stmt: &ast::Stmt) -> &[ast::Attribute] {
-    match stmt.node {
+pub(crate) fn get_attrs_from_stmt(stmt: &ast::Stmt) -> &[ast::Attribute] {
+    match stmt.kind {
         ast::StmtKind::Local(ref local) => &local.attrs,
         ast::StmtKind::Item(ref item) => &item.attrs,
         ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => &expr.attrs,
@@ -34,8 +28,23 @@ pub fn get_attrs_from_stmt(stmt: &ast::Stmt) -> &[ast::Attribute] {
     }
 }
 
+pub(crate) fn get_span_without_attrs(stmt: &ast::Stmt) -> Span {
+    match stmt.kind {
+        ast::StmtKind::Local(ref local) => local.span,
+        ast::StmtKind::Item(ref item) => item.span,
+        ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => expr.span,
+        ast::StmtKind::Mac(ref mac) => {
+            let (ref mac, _, _) = **mac;
+            mac.span
+        }
+    }
+}
+
 /// Returns attributes that are within `outer_span`.
-pub fn filter_inline_attrs(attrs: &[ast::Attribute], outer_span: Span) -> Vec<ast::Attribute> {
+pub(crate) fn filter_inline_attrs(
+    attrs: &[ast::Attribute],
+    outer_span: Span,
+) -> Vec<ast::Attribute> {
     attrs
         .iter()
         .filter(|a| outer_span.lo() <= a.span.lo() && a.span.hi() <= outer_span.hi())
@@ -44,16 +53,15 @@ pub fn filter_inline_attrs(attrs: &[ast::Attribute], outer_span: Span) -> Vec<as
 }
 
 fn is_derive(attr: &ast::Attribute) -> bool {
-    attr.check_name("derive")
+    attr.check_name(sym::derive)
 }
 
 /// Returns the arguments of `#[derive(...)]`.
-fn get_derive_spans(attr: &ast::Attribute) -> Option<Vec<Span>> {
+fn get_derive_spans<'a>(attr: &'a ast::Attribute) -> Option<impl Iterator<Item = Span> + 'a> {
     attr.meta_item_list().map(|meta_item_list| {
         meta_item_list
-            .iter()
-            .map(|nested_meta_item| nested_meta_item.span)
-            .collect()
+            .into_iter()
+            .map(|nested_meta_item| nested_meta_item.span())
     })
 }
 
@@ -63,7 +71,7 @@ fn argument_shape(
     right: usize,
     combine: bool,
     shape: Shape,
-    context: &RewriteContext,
+    context: &RewriteContext<'_>,
 ) -> Option<Shape> {
     match context.config.indent_style() {
         IndentStyle::Block => {
@@ -88,7 +96,7 @@ fn format_derive(
     derive_args: &[Span],
     prefix: &str,
     shape: Shape,
-    context: &RewriteContext,
+    context: &RewriteContext<'_>,
 ) -> Option<String> {
     let mut result = String::with_capacity(128);
     result.push_str(prefix);
@@ -121,7 +129,7 @@ fn format_derive(
 /// Returns the first group of attributes that fills the given predicate.
 /// We consider two doc comments are in different group if they are separated by normal comments.
 fn take_while_with_pred<'a, P>(
-    context: &RewriteContext,
+    context: &RewriteContext<'_>,
     attrs: &'a [ast::Attribute],
     pred: P,
 ) -> &'a [ast::Attribute]
@@ -152,7 +160,7 @@ fn take_while_with_pred<'a, P>(
 
 /// Rewrite the any doc comments which come before any other attributes.
 fn rewrite_initial_doc_comments(
-    context: &RewriteContext,
+    context: &RewriteContext<'_>,
     attrs: &[ast::Attribute],
     shape: Shape,
 ) -> Option<(usize, Option<String>)> {
@@ -181,10 +189,10 @@ fn rewrite_initial_doc_comments(
 }
 
 impl Rewrite for ast::NestedMetaItem {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        match self.node {
-            ast::NestedMetaItemKind::MetaItem(ref meta_item) => meta_item.rewrite(context, shape),
-            ast::NestedMetaItemKind::Literal(ref l) => rewrite_literal(context, l, shape),
+    fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        match self {
+            ast::NestedMetaItem::MetaItem(ref meta_item) => meta_item.rewrite(context, shape),
+            ast::NestedMetaItem::Literal(ref l) => rewrite_literal(context, l, shape),
         }
     }
 }
@@ -209,14 +217,14 @@ fn has_newlines_before_after_comment(comment: &str) -> (&str, &str) {
 }
 
 impl Rewrite for ast::MetaItem {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        Some(match self.node {
+    fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        Some(match self.kind {
             ast::MetaItemKind::Word => {
-                rewrite_path(context, PathContext::Type, None, &self.ident, shape)?
+                rewrite_path(context, PathContext::Type, None, &self.path, shape)?
             }
             ast::MetaItemKind::List(ref list) => {
-                let path = rewrite_path(context, PathContext::Type, None, &self.ident, shape)?;
-                let has_trailing_comma = ::expr::span_ends_with_comma(context, self.span);
+                let path = rewrite_path(context, PathContext::Type, None, &self.path, shape)?;
+                let has_trailing_comma = crate::expr::span_ends_with_comma(context, self.span);
                 overflow::rewrite_with_parens(
                     context,
                     &path,
@@ -233,7 +241,7 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
                 )?
             }
             ast::MetaItemKind::NameValue(ref literal) => {
-                let path = rewrite_path(context, PathContext::Type, None, &self.ident, shape)?;
+                let path = rewrite_path(context, PathContext::Type, None, &self.path, shape)?;
                 // 3 = ` = `
                 let lit_shape = shape.shrink_left(path.len() + 3)?;
                 // `rewrite_literal` returns `None` when `literal` exceeds max
@@ -256,7 +264,7 @@ fn format_arg_list<I, T, F1, F2, F3>(
     get_hi: F2,
     get_item_string: F3,
     span: Span,
-    context: &RewriteContext,
+    context: &RewriteContext<'_>,
     shape: Shape,
     one_line_shape: Shape,
     one_line_limit: Option<usize>,
@@ -306,31 +314,34 @@ fn format_arg_list<I, T, F1, F2, F3>(
 }
 
 impl Rewrite for ast::Attribute {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
+    fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
         let snippet = context.snippet(self.span);
         if self.is_sugared_doc {
             rewrite_doc_comment(snippet, shape.comment(context.config), context.config)
         } else {
+            let should_skip = self
+                .ident()
+                .map(|s| context.skip_context.skip_attribute(&s.name.as_str()))
+                .unwrap_or(false);
             let prefix = attr_prefix(self);
 
-            if contains_comment(snippet) {
+            if should_skip || contains_comment(snippet) {
                 return Some(snippet.to_owned());
             }
 
             if let Some(ref meta) = self.meta() {
                 // This attribute is possibly a doc attribute needing normalization to a doc comment
-                if context.config.normalize_doc_attributes() && meta.check_name("doc") {
+                if context.config.normalize_doc_attributes() && meta.check_name(sym::doc) {
                     if let Some(ref literal) = meta.value_str() {
                         let comment_style = match self.style {
                             ast::AttrStyle::Inner => CommentStyle::Doc,
                             ast::AttrStyle::Outer => CommentStyle::TripleSlash,
                         };
 
-                        // Remove possible whitespace from the `CommentStyle::opener()` so that
-                        // the literal itself has control over the comment's leading spaces.
-                        let opener = comment_style.opener().trim_end();
-
-                        let doc_comment = format!("{}{}", opener, literal);
+                        let literal_str = literal.as_str();
+                        let doc_comment_formatter =
+                            DocCommentFormatter::new(&*literal_str, comment_style);
+                        let doc_comment = format!("{}", doc_comment_formatter);
                         return rewrite_doc_comment(
                             &doc_comment,
                             shape.comment(context.config),
@@ -353,7 +364,7 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
 }
 
 impl<'a> Rewrite for [ast::Attribute] {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
+    fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
         if self.is_empty() {
             return Some(String::new());
         }
@@ -383,7 +394,7 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
                 if let Some(missing_span) = missing_span {
                     let snippet = context.snippet(missing_span);
                     let (mla, mlb) = has_newlines_before_after_comment(snippet);
-                    let comment = ::comment::recover_missing_comment_in_span(
+                    let comment = crate::comment::recover_missing_comment_in_span(
                         missing_span,
                         shape.with_max_width(context.config),
                         context,
@@ -406,10 +417,11 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
             // Handle derives if we will merge them.
             if context.config.merge_derives() && is_derive(&attrs[0]) {
                 let derives = take_while_with_pred(context, attrs, is_derive);
-                let mut derive_spans = vec![];
-                for derive in derives {
-                    derive_spans.append(&mut get_derive_spans(derive)?);
-                }
+                let derive_spans: Vec<_> = derives
+                    .iter()
+                    .filter_map(get_derive_spans)
+                    .flatten()
+                    .collect();
                 let derive_str =
                     format_derive(&derive_spans, attr_prefix(&attrs[0]), shape, context)?;
                 result.push_str(&derive_str);
@@ -418,7 +430,7 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
                     .get(derives.len())
                     .map(|next| mk_sp(attrs[derives.len() - 1].span.hi(), next.span.lo()));
                 if let Some(missing_span) = missing_span {
-                    let comment = ::comment::recover_missing_comment_in_span(
+                    let comment = crate::comment::recover_missing_comment_in_span(
                         missing_span,
                         shape.with_max_width(context.config),
                         context,
@@ -451,7 +463,7 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
                 .get(1)
                 .map(|next| mk_sp(attrs[0].span.hi(), next.span.lo()));
             if let Some(missing_span) = missing_span {
-                let comment = ::comment::recover_missing_comment_in_span(
+                let comment = crate::comment::recover_missing_comment_in_span(
                     missing_span,
                     shape.with_max_width(context.config),
                     context,
@@ -480,3 +492,36 @@ fn attr_prefix(attr: &ast::Attribute) -> &'static str {
         ast::AttrStyle::Outer => "#",
     }
 }
+
+pub(crate) trait MetaVisitor<'ast> {
+    fn visit_meta_item(&mut self, meta_item: &'ast ast::MetaItem) {
+        match meta_item.kind {
+            ast::MetaItemKind::Word => self.visit_meta_word(meta_item),
+            ast::MetaItemKind::List(ref list) => self.visit_meta_list(meta_item, list),
+            ast::MetaItemKind::NameValue(ref lit) => self.visit_meta_name_value(meta_item, lit),
+        }
+    }
+
+    fn visit_meta_list(
+        &mut self,
+        _meta_item: &'ast ast::MetaItem,
+        list: &'ast [ast::NestedMetaItem],
+    ) {
+        for nm in list {
+            self.visit_nested_meta_item(nm);
+        }
+    }
+
+    fn visit_meta_word(&mut self, _meta_item: &'ast ast::MetaItem) {}
+
+    fn visit_meta_name_value(&mut self, _meta_item: &'ast ast::MetaItem, _lit: &'ast ast::Lit) {}
+
+    fn visit_nested_meta_item(&mut self, nm: &'ast ast::NestedMetaItem) {
+        match nm {
+            ast::NestedMetaItem::MetaItem(ref meta_item) => self.visit_meta_item(meta_item),
+            ast::NestedMetaItem::Literal(ref lit) => self.visit_literal(lit),
+        }
+    }
+
+    fn visit_literal(&mut self, _lit: &'ast ast::Lit) {}
+}