From 7d1efa7f266c9aa17da9a8545f23343d4b7559c5 Mon Sep 17 00:00:00 2001 From: Sophie Atkins Date: Wed, 3 Jul 2024 20:28:08 +0200 Subject: [PATCH] hover scalar reference types in models --- prisma-fmt/src/hover.rs | 31 ++++++++++++++++--- .../composite_from_field_type/result.json | 6 ++++ .../composite_from_field_type/schema.prisma | 14 +++++++++ .../enum_from_field_type/result.json | 6 ++++ .../enum_from_field_type/schema.prisma | 16 ++++++++++ prisma-fmt/tests/hover/tests.rs | 2 ++ .../src/walkers/scalar_field.rs | 5 +++ 7 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 prisma-fmt/tests/hover/scenarios/composite_from_field_type/result.json create mode 100644 prisma-fmt/tests/hover/scenarios/composite_from_field_type/schema.prisma create mode 100644 prisma-fmt/tests/hover/scenarios/enum_from_field_type/result.json create mode 100644 prisma-fmt/tests/hover/scenarios/enum_from_field_type/schema.prisma diff --git a/prisma-fmt/src/hover.rs b/prisma-fmt/src/hover.rs index db04839ae85c..a3ce01fbe3bd 100644 --- a/prisma-fmt/src/hover.rs +++ b/prisma-fmt/src/hover.rs @@ -3,7 +3,7 @@ use lsp_types::{Hover, HoverContents, HoverParams, MarkupContent, MarkupKind}; use psl::{ error_tolerant_parse_configuration, parser_database::ParserDatabase, - schema_ast::ast::{self, Field, FieldPosition, ModelPosition, WithDocumentation}, + schema_ast::ast::{self, Field, FieldPosition, ModelPosition, WithDocumentation, WithName}, Diagnostics, SourceFile, }; @@ -48,14 +48,16 @@ fn hover(ctx: HoverContext<'_>) -> Option { let position = match ctx.position() { Some(pos) => pos, None => { + warn!("Received a position outside of the document boundaries in HoverParams"); warn!("Received a position outside of the document boundaries in HoverParams"); return None; } }; let ast = ctx.db.ast(ctx.initiating_file_id); - let contents = match ast.find_at_position(position) { + let contents = match dbg!(ast.find_at_position(position)) { psl::schema_ast::ast::SchemaPosition::TopLevel => None, + psl::schema_ast::ast::SchemaPosition::Model(model_id, ModelPosition::Name(name)) => { let walker = ctx.db.walk((ctx.initiating_file_id, model_id)); let model = walker.ast_model(); @@ -76,7 +78,28 @@ fn hover(ctx: HoverContext<'_>) -> Option { let initiating_field = &ctx.db.walk((ctx.initiating_file_id, model_id)).field(field_id); match initiating_field.refine() { - psl::parser_database::walkers::RefinedFieldWalker::Scalar(_) => None, + psl::parser_database::walkers::RefinedFieldWalker::Scalar(scalar) => match scalar.scalar_field_type() { + psl::parser_database::ScalarFieldType::CompositeType(_) => { + let ct = scalar.field_type_as_composite_type().unwrap(); + Some(format_hover_content( + ct.ast_composite_type().documentation().unwrap_or_default(), + "type", + ct.ast_composite_type().name(), + None, + )) + } + psl::parser_database::ScalarFieldType::Enum(_) => { + let enm = scalar.field_type_as_enum().unwrap(); + Some(format_hover_content( + enm.ast_enum().documentation().unwrap_or_default(), + "enum", + enm.ast_enum().name(), + None, + )) + } + _ => None, + }, + psl::parser_database::walkers::RefinedFieldWalker::Relation(rf) => { let relation = rf.relation(); let opposite_model = rf.related_model(); @@ -134,7 +157,7 @@ fn format_hover_content( (format!("\n\t...\n\t{field}\n"), format!("{rk}{fancy_line_break}")) }); let prisma_display = match variant { - "model" | "enum" | "view" | "composite type" => { + "model" | "enum" | "view" | "type" => { format!("```prisma\n{variant} {top_name} {{{field}}}\n```{fancy_line_break}{relation_kind}") } _ => "".to_owned(), diff --git a/prisma-fmt/tests/hover/scenarios/composite_from_field_type/result.json b/prisma-fmt/tests/hover/scenarios/composite_from_field_type/result.json new file mode 100644 index 000000000000..fe56452d5653 --- /dev/null +++ b/prisma-fmt/tests/hover/scenarios/composite_from_field_type/result.json @@ -0,0 +1,6 @@ +{ + "contents": { + "kind": "markdown", + "value": "```prisma\ntype Address {}\n```\n___\nAddress Doc" + } +} \ No newline at end of file diff --git a/prisma-fmt/tests/hover/scenarios/composite_from_field_type/schema.prisma b/prisma-fmt/tests/hover/scenarios/composite_from_field_type/schema.prisma new file mode 100644 index 000000000000..e43eca95795e --- /dev/null +++ b/prisma-fmt/tests/hover/scenarios/composite_from_field_type/schema.prisma @@ -0,0 +1,14 @@ +datasource db { + provider = "mongodb" + url = env("DATABASE_URL") +} + +model User { + id String @id @map("_id") + address Add<|>ress +} + +/// Address Doc +type Address { + street String +} diff --git a/prisma-fmt/tests/hover/scenarios/enum_from_field_type/result.json b/prisma-fmt/tests/hover/scenarios/enum_from_field_type/result.json new file mode 100644 index 000000000000..a072fe175d82 --- /dev/null +++ b/prisma-fmt/tests/hover/scenarios/enum_from_field_type/result.json @@ -0,0 +1,6 @@ +{ + "contents": { + "kind": "markdown", + "value": "```prisma\nenum Animal {}\n```\n___\n" + } +} \ No newline at end of file diff --git a/prisma-fmt/tests/hover/scenarios/enum_from_field_type/schema.prisma b/prisma-fmt/tests/hover/scenarios/enum_from_field_type/schema.prisma new file mode 100644 index 000000000000..8f1b6cfdc826 --- /dev/null +++ b/prisma-fmt/tests/hover/scenarios/enum_from_field_type/schema.prisma @@ -0,0 +1,16 @@ +datasource db { + provider = "mongodb" + url = env("DATABASE_URL") +} + +model User { + id String @id @map("_id") + pet Ani<|>mal +} + +// Animal Doc +enum Animal { + REDPANDA + CAT + DOG +} diff --git a/prisma-fmt/tests/hover/tests.rs b/prisma-fmt/tests/hover/tests.rs index fd0d32852358..084e42b06053 100644 --- a/prisma-fmt/tests/hover/tests.rs +++ b/prisma-fmt/tests/hover/tests.rs @@ -12,6 +12,8 @@ macro_rules! scenarios { } scenarios! { + composite_from_field_type + enum_from_field_type model_from_block_name model_from_view_type one_to_many_self_relation diff --git a/psl/parser-database/src/walkers/scalar_field.rs b/psl/parser-database/src/walkers/scalar_field.rs index 7a9a0984584a..e36fd9d38dbe 100644 --- a/psl/parser-database/src/walkers/scalar_field.rs +++ b/psl/parser-database/src/walkers/scalar_field.rs @@ -108,6 +108,11 @@ impl<'db> ScalarFieldWalker<'db> { self.scalar_field_type().as_enum().map(|id| self.db.walk(id)) } + /// Is this field's type an enum? If yes, walk the enum. + pub fn field_type_as_composite_type(self) -> Option> { + self.scalar_field_type().as_composite_type().map(|id| self.db.walk(id)) + } + /// The name in the `@map()` attribute. pub fn mapped_name(self) -> Option<&'db str> { self.attributes().mapped_name.map(|id| &self.db[id])