use std::path::Path;
use ktrs_editorconfig::{EnumValue, ParseException};
use crate::editorconfig::{
CODE_STYLE_PROPERTY, CODE_STYLE_PROPERTY_TYPE, CodeStyleValue, END_OF_LINE_PROPERTY,
EXPERIMENTAL_RULES_EXECUTION_PROPERTY, PropertyRef,
};
use crate::engine::editor_config_defaults::{EditorConfigDefaults, EditorConfigOverride};
use crate::engine::editor_config_loader::{EditorConfigLoader, EditorConfigLoaderEc4j};
use crate::engine::formatter_tags::{
FORMATTER_TAG_OFF_ENABLED_PROPERTY, FORMATTER_TAG_ON_ENABLED_PROPERTY,
FORMATTER_TAGS_ENABLED_PROPERTY,
};
use crate::engine::ktlint_rule_engine::KtLintRuleEngine;
use crate::rule_provider::property_types;
const LINE_SEPARATOR: &str = if cfg!(windows) { "\r\n" } else { "\n" };
impl KtLintRuleEngine {
pub fn generate_kotlin_editor_config_section(&self, file_path: &Path) -> Result<String, ParseException> {
let code_style = self
.editor_config_override()
.get(&PropertyRef::from(&*CODE_STYLE_PROPERTY))
.and_then(|value| CODE_STYLE_PROPERTY_TYPE.parse(value.source()).into_parsed())
.unwrap_or(CODE_STYLE_PROPERTY.default_value);
let mut used_editor_config_properties: Vec<PropertyRef> = Vec::new();
for property in self.rule_providers().iter().flat_map(|p| p.uses_editor_config_properties()) {
if !used_editor_config_properties.iter().any(|p| p.identity() == property.identity()) {
used_editor_config_properties.push(property.clone());
}
}
used_editor_config_properties.extend(default_editor_config_properties());
let editor_config = load_editor_config(self, code_style, file_path)?
.add_properties_with_default_value_if_missing(&used_editor_config_properties);
let mut lines: Vec<String> = Vec::new();
for line in editor_config.map(|p| format!("{} = {}", p.name(), p.source_value().unwrap_or("null"))) {
if !lines.contains(&line) {
lines.push(line);
}
}
lines.sort_by(|a, b| a.encode_utf16().cmp(b.encode_utf16()));
Ok(lines.join(LINE_SEPARATOR))
}
}
fn default_editor_config_properties() -> [PropertyRef; 6] {
[
PropertyRef::from(&*CODE_STYLE_PROPERTY),
PropertyRef::from(&*EXPERIMENTAL_RULES_EXECUTION_PROPERTY),
PropertyRef::from(&*END_OF_LINE_PROPERTY),
PropertyRef::from(&*FORMATTER_TAGS_ENABLED_PROPERTY),
PropertyRef::from(&*FORMATTER_TAG_OFF_ENABLED_PROPERTY),
PropertyRef::from(&*FORMATTER_TAG_ON_ENABLED_PROPERTY),
]
}
fn load_editor_config(
engine: &KtLintRuleEngine,
code_style: CodeStyleValue,
file_path: &Path,
) -> Result<crate::editorconfig::EditorConfig, ParseException> {
EditorConfigLoader::new(
EditorConfigLoaderEc4j::new(&property_types(engine.rule_providers())),
EditorConfigDefaults::empty(),
EditorConfigOverride::from(vec![(
PropertyRef::from(&*CODE_STYLE_PROPERTY),
Some(code_style.name().to_owned()),
)]),
)
.load(Some(file_path))
}