Skip to content

Commit

Permalink
fix(fmt): quick-fix create new block (#4890)
Browse files Browse the repository at this point in the history
* Something broke in the definition for these quickfixes in language-tools so this is an opportunistic to both fix and move them to engines.

Reference: https://github.com/prisma/language-tools/blob/53e70077abbcf26c03c8aabb416521dba248804b/packages/language-server/src/lib/code-actions/index.ts#L137-L166

* Also added block qfs for composite types
- enum
- type
  • Loading branch information
Druue committed May 30, 2024
1 parent aa2d11f commit 2f3a869
Show file tree
Hide file tree
Showing 13 changed files with 475 additions and 4 deletions.
11 changes: 10 additions & 1 deletion prisma-fmt/src/code_actions.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod block;
mod mongodb;
mod multi_schema;
mod relation_mode;
Expand Down Expand Up @@ -101,6 +102,8 @@ pub(crate) fn available_actions(
.walk_models_in_file(initiating_file_id)
.chain(validated_schema.db.walk_views_in_file(initiating_file_id))
{
block::create_missing_block_for_model(&mut actions, &context, model);

if config.preview_features().contains(PreviewFeature::MultiSchema) {
multi_schema::add_schema_block_attribute_model(&mut actions, &context, model);

Expand All @@ -114,9 +117,15 @@ pub(crate) fn available_actions(
}
}

if matches!(datasource, Some(ds) if ds.active_provider == "mongodb") {
for composite_type in validated_schema.db.walk_composite_types_in_file(initiating_file_id) {
block::create_missing_block_for_type(&mut actions, &context, composite_type);
}
}

for enumerator in validated_schema.db.walk_enums_in_file(initiating_file_id) {
if config.preview_features().contains(PreviewFeature::MultiSchema) {
multi_schema::add_schema_block_attribute_enum(&mut actions, &context, enumerator)
multi_schema::add_schema_block_attribute_enum(&mut actions, &context, enumerator);
}
}

Expand Down
130 changes: 130 additions & 0 deletions prisma-fmt/src/code_actions/block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
use std::collections::HashMap;

use lsp_types::{CodeAction, CodeActionKind, CodeActionOrCommand, Diagnostic, Range, TextEdit, Url, WorkspaceEdit};
use psl::{
diagnostics::Span,
parser_database::walkers::{CompositeTypeWalker, ModelWalker},
schema_ast::ast::WithSpan,
};

use super::CodeActionsContext;

pub(super) fn create_missing_block_for_model(
actions: &mut Vec<CodeActionOrCommand>,
context: &CodeActionsContext<'_>,
model: ModelWalker<'_>,
) {
let span_model = model.ast_model().span();
let diagnostics = context
.diagnostics_for_span_with_message(span_model, "is neither a built-in type, nor refers to another model,");

if diagnostics.is_empty() {
return;
}

let span = Span {
start: span_model.start,
end: span_model.end + 1, // * otherwise it's still not outside the closing brace
file_id: span_model.file_id,
};

let range = super::range_after_span(context.initiating_file_source(), span);

diagnostics.iter().for_each(|diag| {
push_missing_block(
diag,
context.lsp_params.text_document.uri.clone(),
range,
"model",
actions,
);
push_missing_block(
diag,
context.lsp_params.text_document.uri.clone(),
range,
"enum",
actions,
);

if let Some(ds) = context.datasource() {
if ds.active_provider == "mongodb" {
push_missing_block(
diag,
context.lsp_params.text_document.uri.clone(),
range,
"type",
actions,
);
}
}
})
}

pub(super) fn create_missing_block_for_type(
actions: &mut Vec<CodeActionOrCommand>,
context: &CodeActionsContext<'_>,
composite_type: CompositeTypeWalker<'_>,
) {
let span_type = composite_type.ast_composite_type().span;

let diagnostics = context
.diagnostics_for_span_with_message(span_type, "is neither a built-in type, nor refers to another model,");

if diagnostics.is_empty() {
return;
}

let span = Span {
start: span_type.start,
end: span_type.end + 1, // * otherwise it's still not outside the closing brace
file_id: span_type.file_id,
};

let range = super::range_after_span(context.initiating_file_source(), span);
diagnostics.iter().for_each(|diag| {
push_missing_block(
diag,
context.lsp_params.text_document.uri.clone(),
range,
"type",
actions,
);
push_missing_block(
diag,
context.lsp_params.text_document.uri.clone(),
range,
"enum",
actions,
);
})
}

fn push_missing_block(
diag: &Diagnostic,
uri: Url,
range: Range,
block_type: &str,
actions: &mut Vec<CodeActionOrCommand>,
) {
let name: &str = diag.message.split('\"').collect::<Vec<&str>>()[1];
let new_text = format!("\n{block_type} {name} {{\n\n}}\n");
let text = TextEdit { range, new_text };

let mut changes = HashMap::new();
changes.insert(uri, vec![text]);

let edit = WorkspaceEdit {
changes: Some(changes),
..Default::default()
};

let action = CodeAction {
title: format!("Create new {block_type} '{name}'"),
kind: Some(CodeActionKind::QUICKFIX),
edit: Some(edit),
diagnostics: Some(vec![diag.clone()]),
..Default::default()
};

actions.push(CodeActionOrCommand::CodeAction(action))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
[
{
"title": "Create new model 'Animal'",
"kind": "quickfix",
"diagnostics": [
{
"range": {
"start": {
"line": 11,
"character": 11
},
"end": {
"line": 11,
"character": 17
}
},
"severity": 1,
"message": "Type \"Animal\" is neither a built-in type, nor refers to another model, composite type, or enum."
}
],
"edit": {
"changes": {
"file:///path/to/schema.prisma": [
{
"range": {
"start": {
"line": 12,
"character": 1
},
"end": {
"line": 13,
"character": 0
}
},
"newText": "\nmodel Animal {\n\n}\n"
}
]
}
}
},
{
"title": "Create new enum 'Animal'",
"kind": "quickfix",
"diagnostics": [
{
"range": {
"start": {
"line": 11,
"character": 11
},
"end": {
"line": 11,
"character": 17
}
},
"severity": 1,
"message": "Type \"Animal\" is neither a built-in type, nor refers to another model, composite type, or enum."
}
],
"edit": {
"changes": {
"file:///path/to/schema.prisma": [
{
"range": {
"start": {
"line": 12,
"character": 1
},
"end": {
"line": 13,
"character": 0
}
},
"newText": "\nenum Animal {\n\n}\n"
}
]
}
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgres"
url = env("DATABASE_URL")
}

model Kattbjorn {
id String @id
friend Animal
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
[
{
"title": "Create new type 'Animal'",
"kind": "quickfix",
"diagnostics": [
{
"range": {
"start": {
"line": 11,
"character": 11
},
"end": {
"line": 11,
"character": 17
}
},
"severity": 1,
"message": "Type \"Animal\" is neither a built-in type, nor refers to another model, composite type, or enum."
}
],
"edit": {
"changes": {
"file:///path/to/schema.prisma": [
{
"range": {
"start": {
"line": 12,
"character": 1
},
"end": {
"line": 13,
"character": 0
}
},
"newText": "\ntype Animal {\n\n}\n"
}
]
}
}
},
{
"title": "Create new enum 'Animal'",
"kind": "quickfix",
"diagnostics": [
{
"range": {
"start": {
"line": 11,
"character": 11
},
"end": {
"line": 11,
"character": 17
}
},
"severity": 1,
"message": "Type \"Animal\" is neither a built-in type, nor refers to another model, composite type, or enum."
}
],
"edit": {
"changes": {
"file:///path/to/schema.prisma": [
{
"range": {
"start": {
"line": 12,
"character": 1
},
"end": {
"line": 13,
"character": 0
}
},
"newText": "\nenum Animal {\n\n}\n"
}
]
}
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}

type Kattbjorn {
name String
friend Animal
}
Loading

0 comments on commit 2f3a869

Please sign in to comment.