Skip to content

Commit

Permalink
Introduce FormatterSettings
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed Sep 20, 2023
1 parent 9452ec3 commit c5cfb8a
Show file tree
Hide file tree
Showing 16 changed files with 159 additions and 75 deletions.
6 changes: 6 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 25 additions & 7 deletions crates/ruff_cache/src/cache_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use std::borrow::Cow;
use std::collections::hash_map::DefaultHasher;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::hash::{Hash, Hasher};
use std::num::NonZeroU8;
use std::num::{
NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU128, NonZeroU16,
NonZeroU32, NonZeroU64, NonZeroU8,
};
use std::ops::{Deref, DerefMut};
use std::path::{Path, PathBuf};

Expand Down Expand Up @@ -205,14 +208,29 @@ impl CacheKey for i8 {
state.write_i8(*self);
}
}

impl CacheKey for NonZeroU8 {
#[inline]
fn cache_key(&self, state: &mut CacheKeyHasher) {
state.write_u8(self.get());
}
macro_rules! impl_cache_key_non_zero {
($name:ident) => {
impl CacheKey for $name {
#[inline]
fn cache_key(&self, state: &mut CacheKeyHasher) {
self.get().cache_key(state)
}
}
};
}

impl_cache_key_non_zero!(NonZeroU8);
impl_cache_key_non_zero!(NonZeroU16);
impl_cache_key_non_zero!(NonZeroU32);
impl_cache_key_non_zero!(NonZeroU64);
impl_cache_key_non_zero!(NonZeroU128);

impl_cache_key_non_zero!(NonZeroI8);
impl_cache_key_non_zero!(NonZeroI16);
impl_cache_key_non_zero!(NonZeroI32);
impl_cache_key_non_zero!(NonZeroI64);
impl_cache_key_non_zero!(NonZeroI128);

macro_rules! impl_cache_key_tuple {
() => (
impl CacheKey for () {
Expand Down
17 changes: 2 additions & 15 deletions crates/ruff_cli/src/commands/format.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::fmt::{Display, Formatter};
use std::io;
use std::num::NonZeroU16;
use std::path::{Path, PathBuf};
use std::time::Instant;

Expand All @@ -10,12 +9,10 @@ use log::error;
use rayon::iter::Either::{Left, Right};
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use thiserror::Error;
use tracing::{debug, warn};
use tracing::debug;

use ruff_formatter::LineWidth;
use ruff_linter::fs;
use ruff_linter::logging::LogLevel;
use ruff_linter::settings::types::PreviewMode;
use ruff_linter::warn_user_once;
use ruff_python_ast::{PySourceType, SourceType};
use ruff_python_formatter::{format_module, FormatModuleError, PyFormatOptions};
Expand Down Expand Up @@ -76,17 +73,7 @@ pub(crate) fn format(
};

let resolved_settings = resolver.resolve(path, &pyproject_config);

// TODO(micha): Use `formatter` settings instead
let preview = match resolved_settings.linter.preview {
PreviewMode::Enabled => ruff_python_formatter::PreviewMode::Enabled,
PreviewMode::Disabled => ruff_python_formatter::PreviewMode::Disabled,
};
let line_length = resolved_settings.linter.line_length;

let options = PyFormatOptions::from_source_type(source_type)
.with_line_width(LineWidth::from(NonZeroU16::from(line_length)))
.with_preview(preview);
let options = resolved_settings.formatter.to_format_options(source_type);
debug!("Formatting {} with {:?}", path.display(), options);

Some(match catch_unwind(|| format_path(path, options, mode)) {
Expand Down
20 changes: 5 additions & 15 deletions crates/ruff_cli/src/commands/format_stdin.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use std::io::{stdout, Write};
use std::num::NonZeroU16;
use std::path::Path;

use anyhow::Result;
use log::warn;
use ruff_formatter::LineWidth;
use ruff_linter::settings::types::PreviewMode;

use ruff_python_ast::PySourceType;
use ruff_python_formatter::{format_module, PyFormatOptions};
use ruff_workspace::resolver::python_file_at_path;

Expand Down Expand Up @@ -39,18 +37,10 @@ pub(crate) fn format_stdin(cli: &FormatArguments, overrides: &Overrides) -> Resu
// Format the file.
let path = cli.stdin_filename.as_deref();

// TODO(micha): Use Formatter settings
let preview = match pyproject_config.settings.linter.preview {
PreviewMode::Enabled => ruff_python_formatter::PreviewMode::Enabled,
PreviewMode::Disabled => ruff_python_formatter::PreviewMode::Disabled,
};
let line_length = pyproject_config.settings.linter.line_length;

let options = path
.map(PyFormatOptions::from_extension)
.unwrap_or_default()
.with_line_width(LineWidth::from(NonZeroU16::from(line_length)))
.with_preview(preview);
let options = pyproject_config
.settings
.formatter
.to_format_options(path.map(PySourceType::from).unwrap_or_default());

match format_source(path, options, mode) {
Ok(result) => match mode {
Expand Down
7 changes: 2 additions & 5 deletions crates/ruff_dev/src/format_dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use imara_diff::{diff, Algorithm};
use indicatif::ProgressStyle;
#[cfg_attr(feature = "singlethreaded", allow(unused_imports))]
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use ruff_linter::line_width::LineLength;
use serde::Deserialize;
use similar::{ChangeTag, TextDiff};
use tempfile::NamedTempFile;
Expand Down Expand Up @@ -551,10 +550,8 @@ fn format_dir_entry(
let settings = resolver.resolve(&path, pyproject_config);
// That's a bad way of doing this but it's not worth doing something better for format_dev
// TODO(micha) use formatter settings instead
if settings.linter.line_length != LineLength::default() {
options = options.with_line_width(LineWidth::from(NonZeroU16::from(
settings.linter.line_length,
)));
if settings.formatter.line_width != LineWidth::default() {
options = options.with_line_width(settings.formatter.line_width);
}

// Handle panics (mostly in `debug_assert!`)
Expand Down
2 changes: 2 additions & 0 deletions crates/ruff_formatter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ repository = { workspace = true }
license = { workspace = true }

[dependencies]
ruff_cache = { path = "../ruff_cache" }
ruff_macros = { path = "../ruff_macros" }
ruff_text_size = { path = "../ruff_text_size" }

drop_bomb = { version = "0.1.5" }
Expand Down
11 changes: 9 additions & 2 deletions crates/ruff_formatter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ pub use source_code::{SourceCode, SourceCodeSlice};
pub use crate::diagnostics::{ActualStart, FormatError, InvalidDocumentError, PrintError};
pub use format_element::{normalize_newlines, FormatElement, LINE_TERMINATORS};
pub use group_id::GroupId;
use ruff_macros::CacheKey;
use ruff_text_size::{TextRange, TextSize};

#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash, CacheKey)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Default)]
Expand Down Expand Up @@ -116,8 +117,14 @@ impl TryFrom<u8> for IndentWidth {
}
}

impl From<NonZeroU8> for IndentWidth {
fn from(value: NonZeroU8) -> Self {
Self(value)
}
}

/// The maximum visual width to which the formatter should try to limit a line.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, CacheKey)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct LineWidth(NonZeroU16);
Expand Down
3 changes: 2 additions & 1 deletion crates/ruff_formatter/src/printer/printer_options/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{FormatOptions, IndentStyle, IndentWidth, LineWidth};
use ruff_macros::CacheKey;

/// Options that affect how the [`crate::Printer`] prints the format tokens
#[derive(Clone, Debug, Eq, PartialEq, Default)]
Expand Down Expand Up @@ -120,7 +121,7 @@ impl SourceMapGeneration {
}
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, CacheKey)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum LineEnding {
/// Line Feed only (\n), common on Linux and macOS as well as inside git repos
Expand Down
2 changes: 2 additions & 0 deletions crates/ruff_python_formatter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ repository = { workspace = true }
license = { workspace = true }

[dependencies]
ruff_cache = { path = "../ruff_cache" }
ruff_formatter = { path = "../ruff_formatter" }
ruff_macros = { path = "../ruff_macros" }
ruff_python_trivia = { path = "../ruff_python_trivia" }
ruff_source_file = { path = "../ruff_source_file" }
ruff_python_ast = { path = "../ruff_python_ast" }
Expand Down
2 changes: 2 additions & 0 deletions crates/ruff_python_formatter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::comments::{
pub use crate::context::PyFormatContext;
pub use crate::options::{MagicTrailingComma, PreviewMode, PyFormatOptions, QuoteStyle};
use crate::verbatim::suppressed_node;
pub use settings::FormatterSettings;

pub(crate) mod builders;
pub mod cli;
Expand All @@ -29,6 +30,7 @@ mod options;
pub(crate) mod other;
pub(crate) mod pattern;
mod prelude;
mod settings;
pub(crate) mod statement;
pub(crate) mod type_param;
mod verbatim;
Expand Down
9 changes: 6 additions & 3 deletions crates/ruff_python_formatter/src/options.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use ruff_formatter::printer::{LineEnding, PrinterOptions, SourceMapGeneration};
use ruff_formatter::{FormatOptions, IndentStyle, IndentWidth, LineWidth};
use ruff_macros::CacheKey;
use ruff_python_ast::PySourceType;
use std::path::Path;
use std::str::FromStr;

/// Resolved options for formatting one individual file. This is different from [`FormatSettings`] which
/// represents the formatting settings for multiple files (the whole project, a subdirectory, ...)
#[derive(Clone, Debug)]
#[cfg_attr(
feature = "serde",
Expand Down Expand Up @@ -176,7 +179,7 @@ impl FormatOptions for PyFormatOptions {
}
}

#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, CacheKey)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
Expand Down Expand Up @@ -230,7 +233,7 @@ impl FromStr for QuoteStyle {
}
}

#[derive(Copy, Clone, Debug, Default)]
#[derive(Copy, Clone, Debug, Default, CacheKey)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
Expand Down Expand Up @@ -261,7 +264,7 @@ impl FromStr for MagicTrailingComma {
}
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, CacheKey)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
pub enum PreviewMode {
Expand Down
49 changes: 49 additions & 0 deletions crates/ruff_python_formatter/src/settings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use std::path::PathBuf;

use ruff_formatter::{FormatOptions, IndentStyle, LineWidth};
use ruff_macros::CacheKey;
use ruff_python_ast::PySourceType;

use crate::{MagicTrailingComma, PreviewMode, PyFormatOptions, QuoteStyle};

#[derive(CacheKey, Clone, Debug)]
pub struct FormatterSettings {
/// The files that are excluded from formatting (but may be linted).
pub exclude: Vec<PathBuf>,

pub preview: PreviewMode,

pub line_width: LineWidth,

pub indent_style: IndentStyle,

pub quote_style: QuoteStyle,

pub magic_trailing_comma: MagicTrailingComma,
}

impl FormatterSettings {
pub fn to_format_options(&self, source_type: PySourceType) -> PyFormatOptions {
PyFormatOptions::from_source_type(source_type)
.with_indent_style(self.indent_style)
.with_quote_style(self.quote_style)
.with_magic_trailing_comma(self.magic_trailing_comma)
.with_preview(self.preview)
.with_line_width(self.line_width)
}
}

impl Default for FormatterSettings {
fn default() -> Self {
let default_options = PyFormatOptions::default();

Self {
exclude: Vec::default(),
preview: PreviewMode::Disabled,
line_width: default_options.line_width(),
indent_style: default_options.indent_style(),
quote_style: default_options.quote_style(),
magic_trailing_comma: default_options.magic_trailing_comma(),
}
}
}
19 changes: 6 additions & 13 deletions crates/ruff_wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
use std::num::NonZeroU16;
use std::path::Path;

use js_sys::Error;
use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;

use ruff_formatter::{FormatResult, Formatted, LineWidth};
use ruff_formatter::{FormatResult, Formatted};
use ruff_linter::directives;
use ruff_linter::line_width::{LineLength, TabSize};
use ruff_linter::linter::{check_path, LinterResult};
use ruff_linter::registry::AsRule;
use ruff_linter::settings::types::{PreviewMode, PythonVersion};
use ruff_linter::settings::types::PythonVersion;
use ruff_linter::settings::{flags, DUMMY_VARIABLE_RGX, PREFIXES};
use ruff_linter::source_kind::SourceKind;
use ruff_python_ast::{Mod, PySourceType};
use ruff_python_codegen::Stylist;
use ruff_python_formatter::{format_node, pretty_comments, PyFormatContext, PyFormatOptions};
use ruff_python_formatter::{format_node, pretty_comments, PyFormatContext};
use ruff_python_index::{CommentRangesBuilder, Indexer};
use ruff_python_parser::lexer::LexResult;
use ruff_python_parser::{parse_tokens, AsMode, Mode};
Expand Down Expand Up @@ -302,15 +301,9 @@ impl<'a> ParsedModule<'a> {

fn format(&self, settings: &Settings) -> FormatResult<Formatted<PyFormatContext>> {
// TODO(konstin): Add an options for py/pyi to the UI (2/2)
// TODO(micha): Use formatter settings instead
let options = PyFormatOptions::from_source_type(PySourceType::default())
.with_preview(match settings.linter.preview {
PreviewMode::Disabled => ruff_python_formatter::PreviewMode::Disabled,
PreviewMode::Enabled => ruff_python_formatter::PreviewMode::Enabled,
})
.with_line_width(LineWidth::from(NonZeroU16::from(
settings.linter.line_length,
)));
let options = settings
.formatter
.to_format_options(PySourceType::default());

format_node(
&self.module,
Expand Down
2 changes: 2 additions & 0 deletions crates/ruff_workspace/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ license = { workspace = true }

[dependencies]
ruff_linter = { path = "../ruff_linter" }
ruff_formatter = { path = "../ruff_formatter" }
ruff_python_formatter = { path = "../ruff_python_formatter" }
ruff_cache = { path = "../ruff_cache" }
ruff_macros = { path = "../ruff_macros" }

Expand Down
Loading

0 comments on commit c5cfb8a

Please sign in to comment.