wit_bindgen::generate!({
path: "../../wit/nginx-lint-plugin.wit",
world: "plugin",
pub_export_macro: true,
});
pub fn convert_spec(sdk_spec: super::PluginSpec) -> nginx_lint::plugin::types::PluginSpec {
nginx_lint::plugin::types::PluginSpec {
name: sdk_spec.name,
category: sdk_spec.category,
description: sdk_spec.description,
api_version: sdk_spec.api_version,
severity: sdk_spec.severity,
why: sdk_spec.why,
bad_example: sdk_spec.bad_example,
good_example: sdk_spec.good_example,
references: sdk_spec.references,
min_nginx_version: sdk_spec.min_nginx_version,
max_nginx_version: sdk_spec.max_nginx_version,
}
}
pub fn convert_severity(severity: super::Severity) -> nginx_lint::plugin::types::Severity {
match severity {
super::Severity::Error => nginx_lint::plugin::types::Severity::Error,
super::Severity::Warning => nginx_lint::plugin::types::Severity::Warning,
}
}
pub fn convert_fix(fix: super::Fix) -> nginx_lint::plugin::types::Fix {
nginx_lint::plugin::types::Fix {
line: fix.line as u32,
old_text: fix.old_text,
new_text: fix.new_text,
delete_line: fix.delete_line,
insert_after: fix.insert_after,
start_offset: fix.start_offset.map(|v| v as u32),
end_offset: fix.end_offset.map(|v| v as u32),
}
}
pub fn convert_lint_error(error: super::LintError) -> nginx_lint::plugin::types::LintError {
nginx_lint::plugin::types::LintError {
rule: error.rule,
category: error.category,
message: error.message,
severity: convert_severity(error.severity),
line: error.line.map(|v| v as u32),
column: error.column.map(|v| v as u32),
fixes: error.fixes.into_iter().map(convert_fix).collect(),
}
}
pub fn reconstruct_config(
config: &nginx_lint::plugin::config_api::Config,
) -> crate::parser::ast::Config {
use crate::parser::ast;
let items = reconstruct_config_items(&config.items());
let include_context = config.include_context();
ast::Config {
items,
include_context,
}
}
fn reconstruct_config_items(
items: &[nginx_lint::plugin::config_api::ConfigItem],
) -> Vec<crate::parser::ast::ConfigItem> {
use crate::parser::ast;
use nginx_lint::plugin::config_api::ConfigItem as WitConfigItem;
items
.iter()
.map(|item| match item {
WitConfigItem::DirectiveItem(dir_handle) => {
ast::ConfigItem::Directive(Box::new(reconstruct_directive(dir_handle)))
}
WitConfigItem::CommentItem(c) => ast::ConfigItem::Comment(ast::Comment {
text: c.text.clone(),
span: ast::Span::new(
ast::Position::new(c.line as usize, c.column as usize, c.start_offset as usize),
ast::Position::new(
c.line as usize,
c.column as usize + c.text.chars().count(),
c.end_offset as usize,
),
),
leading_whitespace: c.leading_whitespace.clone(),
trailing_whitespace: c.trailing_whitespace.clone(),
}),
WitConfigItem::BlankLineItem(b) => ast::ConfigItem::BlankLine(ast::BlankLine {
span: ast::Span::new(
ast::Position::new(b.line as usize, 1, b.start_offset as usize),
ast::Position::new(
b.line as usize,
1 + b.content.chars().count(),
b.start_offset as usize + b.content.len(),
),
),
content: b.content.clone(),
}),
})
.collect()
}
fn convert_wit_argument(
a: &nginx_lint::plugin::config_api::ArgumentInfo,
) -> crate::parser::ast::Argument {
use crate::parser::ast;
let value = match a.arg_type {
nginx_lint::plugin::config_api::ArgumentType::Literal => {
ast::ArgumentValue::Literal(a.value.clone())
}
nginx_lint::plugin::config_api::ArgumentType::QuotedString => {
ast::ArgumentValue::QuotedString(a.value.clone())
}
nginx_lint::plugin::config_api::ArgumentType::SingleQuotedString => {
ast::ArgumentValue::SingleQuotedString(a.value.clone())
}
nginx_lint::plugin::config_api::ArgumentType::Variable => {
ast::ArgumentValue::Variable(a.value.clone())
}
};
ast::Argument {
value,
span: ast::Span::new(
ast::Position::new(a.line as usize, a.column as usize, a.start_offset as usize),
ast::Position::new(
a.line as usize,
a.column as usize + a.raw.chars().count(),
a.end_offset as usize,
),
),
raw: a.raw.clone(),
}
}
fn reconstruct_directive(
handle: &nginx_lint::plugin::config_api::Directive,
) -> crate::parser::ast::Directive {
use crate::parser::ast;
let d = handle.data();
let args: Vec<ast::Argument> = d.args.iter().map(convert_wit_argument).collect();
let line = d.line as usize;
let column = d.column as usize;
let start_offset = d.start_offset as usize;
let end_offset = d.end_offset as usize;
let end_line = d.end_line as usize;
let end_column = d.end_column as usize;
let block = if d.has_block {
let block_items = reconstruct_config_items(&handle.block_items());
let block_start_line = d.block_start_line.unwrap_or(line as u32) as usize;
let block_start_column = d.block_start_column.unwrap_or(column as u32) as usize;
let block_start_offset = d.block_start_offset.unwrap_or(start_offset as u32) as usize;
Some(ast::Block {
items: block_items,
span: ast::Span::new(
ast::Position::new(block_start_line, block_start_column, block_start_offset),
ast::Position::new(end_line, end_column, end_offset),
),
raw_content: d.block_raw_content,
closing_brace_leading_whitespace: d
.closing_brace_leading_whitespace
.unwrap_or_default(),
trailing_whitespace: d.block_trailing_whitespace.unwrap_or_default(),
})
} else {
None
};
let name_end_column = d.name_end_column as usize;
let name_end_offset = d.name_end_offset as usize;
let trailing_comment = d.trailing_comment_text.map(|text| ast::Comment {
span: ast::Span::new(
ast::Position::new(line, 0, 0),
ast::Position::new(line, 0, 0),
),
leading_whitespace: String::new(),
trailing_whitespace: String::new(),
text,
});
ast::Directive {
name: d.name,
name_span: ast::Span::new(
ast::Position::new(line, column, start_offset),
ast::Position::new(line, name_end_column, name_end_offset),
),
args,
block,
span: ast::Span::new(
ast::Position::new(line, column, start_offset),
ast::Position::new(end_line, end_column, end_offset),
),
trailing_comment,
leading_whitespace: d.leading_whitespace,
space_before_terminator: d.space_before_terminator,
trailing_whitespace: d.trailing_whitespace,
}
}