diff --git a/prisma-fmt/src/code_actions.rs b/prisma-fmt/src/code_actions.rs index e62efddc0a07..86b5622768a5 100644 --- a/prisma-fmt/src/code_actions.rs +++ b/prisma-fmt/src/code_actions.rs @@ -14,7 +14,7 @@ use psl::{ walkers::{ModelWalker, RefinedRelationWalker, ScalarFieldWalker}, SourceFile, }, - schema_ast::ast::{self, Attribute, IndentationType, NewlineType, WithSpan}, + schema_ast::ast::{self, Attribute, IndentationType, NewlineType, WithAttributes, WithSpan}, PreviewFeature, }; use std::collections::HashMap; @@ -181,7 +181,7 @@ fn create_missing_attribute<'a>( &attribute, model.indentation(), model.newline(), - &model.ast_model().attributes, + model.ast_model().attributes(), ); let range = range_after_span(model.ast_model().span(), schema); diff --git a/prisma-fmt/src/code_actions/field.rs b/prisma-fmt/src/code_actions/field.rs index 228e1ea2a36d..bca62019dc6b 100644 --- a/prisma-fmt/src/code_actions/field.rs +++ b/prisma-fmt/src/code_actions/field.rs @@ -51,7 +51,7 @@ pub(super) fn add_missing_opposite_relation( let name_arg = field .ast_field() - .attributes + .attributes() .iter() .find(|attr| attr.name() == "relation") .and_then(|attr| attr.arguments.arguments.iter().find(|arg| arg.value.is_string())); diff --git a/prisma-fmt/src/code_actions/multi_schema.rs b/prisma-fmt/src/code_actions/multi_schema.rs index 309c93aa0d47..ba5e0c496f0c 100644 --- a/prisma-fmt/src/code_actions/multi_schema.rs +++ b/prisma-fmt/src/code_actions/multi_schema.rs @@ -2,7 +2,7 @@ use lsp_types::{CodeAction, CodeActionKind, CodeActionOrCommand}; use psl::{ diagnostics::Span, parser_database::walkers::{EnumWalker, ModelWalker}, - schema_ast::ast::WithSpan, + schema_ast::ast::{WithAttributes, WithSpan}, }; use super::CodeActionsContext; @@ -42,7 +42,7 @@ pub(super) fn add_schema_block_attribute_model( "schema()", model.indentation(), model.newline(), - &model.ast_model().attributes, + model.ast_model().attributes(), ); let Ok(edit) = super::create_text_edit( diff --git a/prisma-fmt/src/code_actions/relation_mode.rs b/prisma-fmt/src/code_actions/relation_mode.rs index 53bd556c9cdc..53fb78beff85 100644 --- a/prisma-fmt/src/code_actions/relation_mode.rs +++ b/prisma-fmt/src/code_actions/relation_mode.rs @@ -1,7 +1,7 @@ use lsp_types::{CodeAction, CodeActionKind, CodeActionOrCommand}; use psl::{ parser_database::walkers::CompleteInlineRelationWalker, - schema_ast::ast::{SourceConfig, WithIdentifier, WithName}, + schema_ast::ast::{SourceConfig, WithIdentifier, WithName, WithSpan}, }; use super::CodeActionsContext; @@ -24,7 +24,7 @@ pub(crate) fn edit_referential_integrity( context.initiating_file_source(), "relationMode".to_owned(), false, - prop.identifier().span, + prop.identifier().span(), ) else { return; }; diff --git a/prisma-fmt/src/code_actions/relations.rs b/prisma-fmt/src/code_actions/relations.rs index 3777e01fe703..62920fdaca3f 100644 --- a/prisma-fmt/src/code_actions/relations.rs +++ b/prisma-fmt/src/code_actions/relations.rs @@ -1,7 +1,10 @@ use lsp_types::{CodeAction, CodeActionKind, CodeActionOrCommand, TextEdit, WorkspaceEdit}; -use psl::parser_database::{ - ast::WithSpan, - walkers::{CompleteInlineRelationWalker, InlineRelationWalker, RelationFieldWalker}, +use psl::{ + parser_database::{ + ast::WithSpan, + walkers::{CompleteInlineRelationWalker, InlineRelationWalker, RelationFieldWalker}, + }, + schema_ast::ast::WithAttributes, }; use std::collections::HashMap; @@ -471,7 +474,7 @@ pub(super) fn add_index_for_relation_fields( &attribute, relation.model().indentation(), relation.model().newline(), - &relation.model().ast_model().attributes, + relation.model().ast_model().attributes(), ); let range = super::range_after_span(relation.model().ast_model().span(), context.initiating_file_source()); diff --git a/prisma-fmt/src/references.rs b/prisma-fmt/src/references.rs index c1da312fc465..11f94f0d65ea 100644 --- a/prisma-fmt/src/references.rs +++ b/prisma-fmt/src/references.rs @@ -267,7 +267,7 @@ fn find_where_used_for_native_type<'ast>( Box::new(fields.filter_map(move |field| { field .1 - .attributes + .attributes() .iter() .find(|attr| extract_ds_from_native_type(attr.name()) == Some(name)) .map(|attr| attr.identifier().span()) @@ -289,7 +289,7 @@ fn find_where_used_as_field_type<'ast>( fn get_relevent_identifiers<'a>(fields: impl Iterator, name: &str) -> Vec { fields .filter_map(|(_id, field)| match &field.field_type { - FieldType::Supported(id) if id.name == name => Some(id.span()), + FieldType::Supported(id) if id.name() == name => Some(id.span()), _ => None, }) .collect() diff --git a/prisma-fmt/tests/text_document_completion/scenarios/referential_actions_with_trailing_comma/schema.prisma b/prisma-fmt/tests/text_document_completion/scenarios/referential_actions_with_trailing_comma/schema.prisma index 912f1153dc37..ce265fe35110 100644 --- a/prisma-fmt/tests/text_document_completion/scenarios/referential_actions_with_trailing_comma/schema.prisma +++ b/prisma-fmt/tests/text_document_completion/scenarios/referential_actions_with_trailing_comma/schema.prisma @@ -10,10 +10,9 @@ model TestB { } model Test { - id Int @id + id Int @id bId Int // The user started typing Casc b TestB @relation(fields: [testBId], references: [id], onDelete: <|>,) testBId Int } - diff --git a/psl/parser-database/src/attributes.rs b/psl/parser-database/src/attributes.rs index b17c3d1a6676..3f66cc140398 100644 --- a/psl/parser-database/src/attributes.rs +++ b/psl/parser-database/src/attributes.rs @@ -568,7 +568,7 @@ fn model_unique(data: &mut ModelAttributes, model_id: crate::ModelId, ctx: &mut }; if let Some(name) = name { - validate_client_name(current_attribute.span, ast_model.name(), name, "@@unique", ctx); + validate_client_name(current_attribute.span(), ast_model.name(), name, "@@unique", ctx); } mapped_name @@ -595,7 +595,7 @@ fn common_index_validations( } }; - match resolve_field_array_with_args(fields, current_attribute.span, model_id, resolving, ctx) { + match resolve_field_array_with_args(fields, current_attribute.span(), model_id, resolving, ctx) { Ok(fields) => { index_data.fields = fields; } @@ -625,7 +625,7 @@ fn common_index_validations( fields.join(", "), ); let model_name = ctx.asts[model_id].name(); - DatamodelError::new_model_validation_error(message, "model", model_name, current_attribute.span) + DatamodelError::new_model_validation_error(message, "model", model_name, current_attribute.span()) }); } @@ -668,7 +668,7 @@ fn common_index_validations( ), "model", ctx.asts[model_id].name(), - current_attribute.span, + current_attribute.span(), )); } } @@ -681,7 +681,7 @@ fn visit_relation(model_id: crate::ModelId, relation_field_id: RelationFieldId, ctx.types[relation_field_id].relation_attribute = Some(ctx.current_attribute_id().1); if let Some(fields) = ctx.visit_optional_arg("fields") { - let fields = match resolve_field_array_without_args(fields, attr.span, model_id, ctx) { + let fields = match resolve_field_array_without_args(fields, attr.span(), model_id, ctx) { Ok(fields) => fields, Err(FieldResolutionError::AlreadyDealtWith) => Vec::new(), Err(FieldResolutionError::ProblematicFields { @@ -722,7 +722,7 @@ fn visit_relation(model_id: crate::ModelId, relation_field_id: RelationFieldId, if let Some(references) = ctx.visit_optional_arg("references") { let references = match resolve_field_array_without_args( references, - attr.span, + attr.span(), ctx.types[relation_field_id].referenced_model, ctx, ) { @@ -745,7 +745,7 @@ fn visit_relation(model_id: crate::ModelId, relation_field_id: RelationFieldId, "The argument `references` must refer only to existing fields in the related model `{model_name}`. The following fields do not exist in the related model: {field_names}", ); - ctx.push_error(DatamodelError::new_validation_error(&msg, attr.span)); + ctx.push_error(DatamodelError::new_validation_error(&msg, attr.span())); } if !relation_fields.is_empty() { @@ -754,7 +754,7 @@ fn visit_relation(model_id: crate::ModelId, relation_field_id: RelationFieldId, ctx.asts[ctx.types[relation_field_id].referenced_model].name(), relation_fields.iter().map(|(f, _)| f.name()).collect::>().join(", "), ); - ctx.push_error(DatamodelError::new_validation_error(&msg, attr.span)); + ctx.push_error(DatamodelError::new_validation_error(&msg, attr.span())); } Vec::new() diff --git a/psl/parser-database/src/attributes/default.rs b/psl/parser-database/src/attributes/default.rs index e2be240f152c..c689bd200245 100644 --- a/psl/parser-database/src/attributes/default.rs +++ b/psl/parser-database/src/attributes/default.rs @@ -1,3 +1,5 @@ +use schema_ast::ast::WithSpan; + use crate::{ ast::{self, WithName}, coerce, @@ -336,7 +338,7 @@ fn validate_default_value_on_composite_type( "Defaults on fields of type composite are not supported. Please remove the `@default` attribute.", ct_name, ast_field.name(), - attr.span, + attr.span(), )); } diff --git a/psl/parser-database/src/attributes/id.rs b/psl/parser-database/src/attributes/id.rs index 13618bbea737..77705b10614e 100644 --- a/psl/parser-database/src/attributes/id.rs +++ b/psl/parser-database/src/attributes/id.rs @@ -19,7 +19,7 @@ pub(super) fn model(model_data: &mut ModelAttributes, model_id: crate::ModelId, let resolving = FieldResolvingSetup::OnlyTopLevel; - let resolved_fields = match resolve_field_array_with_args(fields, attr.span, model_id, resolving, ctx) { + let resolved_fields = match resolve_field_array_with_args(fields, attr.span(), model_id, resolving, ctx) { Ok(fields) => fields, Err(FieldResolutionError::AlreadyDealtWith) => return, Err(FieldResolutionError::ProblematicFields { @@ -61,7 +61,7 @@ pub(super) fn model(model_data: &mut ModelAttributes, model_id: crate::ModelId, &msg, "model", ctx.asts[model_id].name(), - attr.span, + attr.span(), )); } @@ -105,7 +105,7 @@ pub(super) fn model(model_data: &mut ModelAttributes, model_id: crate::ModelId, ), "model", ast_model.name(), - attr.span, + attr.span(), )) } @@ -222,7 +222,7 @@ pub(super) fn validate_id_field_arities( ctx.push_error(DatamodelError::new_attribute_validation_error( "Fields that are marked as id must be required.", "@id", - ctx.asts[pk.source_attribute].span, + ctx.asts[pk.source_attribute].span(), )) } } diff --git a/psl/parser-database/src/attributes/native_types.rs b/psl/parser-database/src/attributes/native_types.rs index 704df89e23ac..8a1f980b2b65 100644 --- a/psl/parser-database/src/attributes/native_types.rs +++ b/psl/parser-database/src/attributes/native_types.rs @@ -1,3 +1,5 @@ +use schema_ast::ast::WithSpan; + use crate::{ast, context::Context, ScalarFieldId, StringId}; pub(super) fn visit_model_field_native_type_attribute( @@ -10,7 +12,7 @@ pub(super) fn visit_model_field_native_type_attribute( let args = &attr.arguments; let args: Vec = args.arguments.iter().map(|arg| arg.value.to_string()).collect(); - ctx.types[id].native_type = Some((datasource_name, type_name, args, attr.span)) + ctx.types[id].native_type = Some((datasource_name, type_name, args, attr.span())) } pub(super) fn visit_composite_type_field_native_type_attribute( @@ -24,6 +26,6 @@ pub(super) fn visit_composite_type_field_native_type_attribute( let args: Vec = args.arguments.iter().map(|arg| arg.value.to_string()).collect(); if let Some(composite_type_field) = ctx.types.composite_type_fields.get_mut(&id) { - composite_type_field.native_type = Some((datasource_name, type_name, args, attr.span)) + composite_type_field.native_type = Some((datasource_name, type_name, args, attr.span())) } } diff --git a/psl/parser-database/src/context.rs b/psl/parser-database/src/context.rs index fb62d8a8b26a..5fa2740c9455 100644 --- a/psl/parser-database/src/context.rs +++ b/psl/parser-database/src/context.rs @@ -5,7 +5,7 @@ use crate::{ ast, interner::StringInterner, names::Names, relations::Relations, types::Types, DatamodelError, Diagnostics, InFile, StringId, }; -use schema_ast::ast::{EnumValueId, Expression, WithName}; +use schema_ast::ast::{EnumValueId, Expression, WithIdentifier, WithName, WithSpan}; use std::collections::{HashMap, HashSet}; /// Validation context. This is an implementation detail of ParserDatabase. It @@ -88,8 +88,11 @@ impl<'db> Context<'db> { pub(crate) fn push_attribute_validation_error(&mut self, message: &str) { let attribute = self.current_attribute(); - let err = - DatamodelError::new_attribute_validation_error(message, &format!("@{}", attribute.name()), attribute.span); + let err = DatamodelError::new_attribute_validation_error( + message, + &format!("@{}", attribute.name()), + attribute.span(), + ); self.push_error(err); } @@ -142,7 +145,7 @@ impl<'db> Context<'db> { /// purely positional. pub(crate) fn visit_datasource_scoped(&mut self) -> Option<(StringId, StringId, crate::AttributeId)> { let attrs = iter_attributes(self.attributes.attributes.as_ref(), self.asts) - .filter(|(_, attr)| attr.name.name.contains('.')); + .filter(|(_, attr)| attr.name().contains('.')); let mut native_type_attr = None; let diagnostics = &mut self.diagnostics; @@ -150,7 +153,7 @@ impl<'db> Context<'db> { for (attr_idx, attr) in attrs { assert!(self.attributes.unused_attributes.remove(&attr_idx)); - match attr.name.name.split_once('.') { + match attr.name().split_once('.') { None => unreachable!(), Some((datasource_name, attr_name)) => { let ds = self.interner.intern(datasource_name); @@ -158,7 +161,7 @@ impl<'db> Context<'db> { if native_type_attr.replace((ds, attr_idx, attr_name)).is_some() { diagnostics.push_error(DatamodelError::new_duplicate_attribute_error( datasource_name, - attr.span, + attr.span(), )); } } @@ -176,7 +179,7 @@ impl<'db> Context<'db> { #[must_use] pub(crate) fn visit_optional_single_attr(&mut self, name: &'static str) -> bool { let mut attrs = - iter_attributes(self.attributes.attributes.as_ref(), self.asts).filter(|(_, a)| a.name.name == name); + iter_attributes(self.attributes.attributes.as_ref(), self.asts).filter(|(_, a)| a.name() == name); let (first_idx, first) = match attrs.next() { Some(first) => first, None => return false, @@ -185,12 +188,9 @@ impl<'db> Context<'db> { if attrs.next().is_some() { for (idx, attr) in - iter_attributes(self.attributes.attributes.as_ref(), self.asts).filter(|(_, a)| a.name.name == name) + iter_attributes(self.attributes.attributes.as_ref(), self.asts).filter(|(_, a)| a.name() == name) { - diagnostics.push_error(DatamodelError::new_duplicate_attribute_error( - &attr.name.name, - attr.span, - )); + diagnostics.push_error(DatamodelError::new_duplicate_attribute_error(attr.name(), attr.span())); assert!(self.attributes.unused_attributes.remove(&idx)); } @@ -210,7 +210,7 @@ impl<'db> Context<'db> { while !has_valid_attribute { let first_attr = iter_attributes(self.attributes.attributes.as_ref(), self.asts) - .filter(|(_, attr)| attr.name.name == name) + .filter(|(_, attr)| attr.name() == name) .find(|(attr_id, _)| self.attributes.unused_attributes.contains(attr_id)); let (attr_id, attr) = if let Some(first_attr) = first_attr { first_attr @@ -243,11 +243,11 @@ impl<'db> Context<'db> { } (Some(arg_idx), Some(_)) => { let arg = self.arg_at(arg_idx); - Err(DatamodelError::new_duplicate_default_argument_error(name, arg.span)) + Err(DatamodelError::new_duplicate_default_argument_error(name, arg.span())) } (None, None) => Err(DatamodelError::new_argument_not_found_error( name, - self.current_attribute().span, + self.current_attribute().span(), )), } } @@ -279,7 +279,7 @@ impl<'db> Context<'db> { let diagnostics = &mut self.diagnostics; for arg_idx in self.attributes.args.values() { let arg = &attr.arguments.arguments[*arg_idx]; - diagnostics.push_error(DatamodelError::new_unused_argument_error(arg.span)); + diagnostics.push_error(DatamodelError::new_unused_argument_error(arg.span())); } self.discard_arguments(); @@ -296,8 +296,8 @@ impl<'db> Context<'db> { for attribute_id in &self.attributes.unused_attributes { let attribute = &self.asts[*attribute_id]; diagnostics.push_error(DatamodelError::new_attribute_not_known_error( - &attribute.name.name, - attribute.span, + attribute.name(), + attribute.span(), )) } @@ -360,9 +360,9 @@ impl<'db> Context<'db> { for args in all_arguments_lists { for arg in &args.empty_arguments { self.push_error(DatamodelError::new_attribute_validation_error( - &format!("The `{}` argument is missing a value.", arg.name.name), + &format!("The `{}` argument is missing a value.", arg.name()), &format!("@{}", attribute.name()), - arg.name.span, + arg.identifier().span(), )); is_reasonably_valid = false; } @@ -381,9 +381,9 @@ impl<'db> Context<'db> { for arg in args.empty_arguments.iter() { self.push_error(DatamodelError::new_attribute_validation_error( - &format!("The `{}` argument is missing a value.", arg.name.name), + &format!("The `{}` argument is missing a value.", arg.name()), &format!("@@{}", attribute.name()), - arg.name.span, + arg.identifier().span(), )); } } @@ -410,7 +410,7 @@ impl<'db> Context<'db> { let mut unnamed_arguments = Vec::new(); for (arg_idx, arg) in arguments.arguments.iter().enumerate() { - let arg_name = arg.name.as_ref().map(|name| self.interner.intern(&name.name)); + let arg_name = arg.name().map(|name| self.interner.intern(name)); if let Some(existing_argument) = self.attributes.args.insert(arg_name, arg_idx) { if arg.is_unnamed() { if unnamed_arguments.is_empty() { @@ -421,8 +421,8 @@ impl<'db> Context<'db> { unnamed_arguments.push(arg.value.to_string()) } else { self.push_error(DatamodelError::new_duplicate_argument_error( - &arg.name.as_ref().unwrap().name, - arg.span, + arg.name().unwrap(), + arg.span(), )); } } diff --git a/psl/parser-database/src/names.rs b/psl/parser-database/src/names.rs index 4f2cca1bc5cb..9d641b66dcfe 100644 --- a/psl/parser-database/src/names.rs +++ b/psl/parser-database/src/names.rs @@ -46,14 +46,14 @@ pub(super) fn resolve_names(ctx: &mut Context<'_>) { validate_attribute_identifiers(ast_enum, ctx); for value in &ast_enum.values { - validate_identifier(&value.name, "Enum Value", ctx); + validate_identifier(value.identifier(), "Enum Value", ctx); validate_attribute_identifiers(value, ctx); - if !tmp_names.insert(&value.name.name) { + if !tmp_names.insert(value.name()) { ctx.push_error(DatamodelError::new_duplicate_enum_value_error( ast_enum.name(), - &value.name.name, - value.span, + value.name(), + value.span(), )) } } @@ -79,7 +79,7 @@ pub(super) fn resolve_names(ctx: &mut Context<'_>) { model.name(), field.name(), "view", - field.identifier().span, + field.identifier().span(), )) } } @@ -105,7 +105,7 @@ pub(super) fn resolve_names(ctx: &mut Context<'_>) { model.name(), field.name(), "model", - field.identifier().span, + field.identifier().span(), )) } } @@ -168,13 +168,16 @@ fn duplicate_top_error(existing: &ast::Top, duplicate: &ast::Top) -> DatamodelEr duplicate.name(), duplicate.get_type(), existing.get_type(), - duplicate.identifier().span, + duplicate.identifier().span(), ) } fn assert_is_not_a_reserved_scalar_type(ident: &ast::Identifier, ctx: &mut Context<'_>) { - if ScalarType::try_from_str(&ident.name, false).is_some() { - ctx.push_error(DatamodelError::new_reserved_scalar_type_error(&ident.name, ident.span)); + if ScalarType::try_from_str(ident.name(), false).is_some() { + ctx.push_error(DatamodelError::new_reserved_scalar_type_error( + ident.name(), + ident.span(), + )); } } @@ -190,7 +193,7 @@ fn check_for_duplicate_properties<'a>( ctx.push_error(DatamodelError::new_duplicate_config_key_error( &format!("{} \"{}\"", top.get_type(), top.name()), arg.name(), - arg.identifier().span, + arg.identifier().span(), )); } } @@ -198,25 +201,25 @@ fn check_for_duplicate_properties<'a>( fn validate_attribute_identifiers(with_attrs: &dyn WithAttributes, ctx: &mut Context<'_>) { for attribute in with_attrs.attributes() { - validate_identifier(&attribute.name, "Attribute", ctx); + validate_identifier(attribute.identifier(), "Attribute", ctx); } } fn validate_identifier(ident: &ast::Identifier, schema_item: &str, ctx: &mut Context<'_>) { - if ident.name.is_empty() { + if ident.name().is_empty() { ctx.push_error(DatamodelError::new_validation_error( &format!("The name of a {schema_item} must not be empty."), - ident.span, + ident.span(), )) - } else if ident.name.chars().next().unwrap().is_numeric() { + } else if ident.name().chars().next().unwrap().is_numeric() { ctx.push_error(DatamodelError::new_validation_error( &format!("The name of a {schema_item} must not start with a number."), - ident.span, + ident.span(), )) - } else if ident.name.contains('-') { + } else if ident.name().contains('-') { ctx.push_error(DatamodelError::new_validation_error( &format!("The character `-` is not allowed in {schema_item} names."), - ident.span, + ident.span(), )) } } diff --git a/psl/parser-database/src/types.rs b/psl/parser-database/src/types.rs index 7d8a0c6a949f..f5515bd9f7d1 100644 --- a/psl/parser-database/src/types.rs +++ b/psl/parser-database/src/types.rs @@ -661,7 +661,7 @@ fn visit_model<'db>(model_id: crate::ModelId, ast_model: &'db ast::Model, ctx: & .iter_tops() .filter_map(|(_, top)| match top { ast::Top::Source(_) | ast::Top::Generator(_) => None, - _ => Some(&top.identifier().name), + _ => Some(top.name()), }) .collect(); @@ -669,7 +669,7 @@ fn visit_model<'db>(model_id: crate::ModelId, ast_model: &'db ast::Model, ctx: & Some(ignore_case_match) => { ctx.push_error(DatamodelError::new_type_for_case_not_found_error( supported, - ignore_case_match.as_str(), + ignore_case_match, ast_field.field_type.span(), )); } @@ -729,7 +729,7 @@ fn visit_enum<'db>(enm: &'db ast::Enum, ctx: &mut Context<'db>) { /// does not match any we know of. fn field_type<'db>(field: &'db ast::Field, ctx: &mut Context<'db>) -> Result { let supported = match &field.field_type { - ast::FieldType::Supported(ident) => &ident.name, + ast::FieldType::Supported(ident) => ident.name(), ast::FieldType::Unsupported(name, _) => { let unsupported = UnsupportedType::new(ctx.interner.intern(name)); return Ok(FieldType::Scalar(ScalarFieldType::Unsupported(unsupported))); diff --git a/psl/parser-database/src/types/index_fields.rs b/psl/parser-database/src/types/index_fields.rs index 7a0051eeb5fc..a367c0840a03 100644 --- a/psl/parser-database/src/types/index_fields.rs +++ b/psl/parser-database/src/types/index_fields.rs @@ -1,3 +1,5 @@ +use schema_ast::ast::WithSpan; + use crate::{ast, coerce, types::SortOrder, DatamodelError}; pub(crate) enum OperatorClass<'a> { @@ -62,29 +64,28 @@ pub(crate) fn coerce_field_array_with_args<'a>( } fn field_args<'a>(args: &'a [ast::Argument], diagnostics: &mut diagnostics::Diagnostics) -> FieldArguments<'a> { - let sort_order = args - .iter() - .find(|arg| arg.name.as_ref().map(|n| n.name.as_str()) == Some("sort")) - .and_then(|arg| match coerce::constant(&arg.value, diagnostics) { + let sort_order = args.iter().find(|arg| arg.name() == Some("sort")).and_then(|arg| { + match coerce::constant(&arg.value, diagnostics) { Some("Asc") => Some(SortOrder::Asc), Some("Desc") => Some(SortOrder::Desc), Some(_) => { - diagnostics.push_error(DatamodelError::new_parser_error("Asc, Desc".to_owned(), arg.span)); + diagnostics.push_error(DatamodelError::new_parser_error("Asc, Desc".to_owned(), arg.span())); None } None => None, - }); + } + }); let length = args .iter() - .find(|arg| arg.name.as_ref().map(|n| n.name.as_str()) == Some("length")) + .find(|arg| arg.name() == Some("length")) .and_then(|arg| coerce::integer(&arg.value, diagnostics)) .filter(|i| *i >= 0) .map(|i| i as u32); let operator_class = args .iter() - .find(|arg| arg.name.as_ref().map(|n| n.name.as_str()) == Some("ops")) + .find(|arg| arg.name() == Some("ops")) .and_then(|arg| match &arg.value { ast::Expression::ConstantValue(s, span) => match s.as_str() { // gist @@ -184,7 +185,10 @@ fn field_args<'a>(args: &'a [ast::Argument], diagnostics: &mut diagnostics::Diag _ => panic!(), }, _ => { - diagnostics.push_error(DatamodelError::new_parser_error("operator class".to_owned(), arg.span)); + diagnostics.push_error(DatamodelError::new_parser_error( + "operator class".to_owned(), + arg.span(), + )); None } }); diff --git a/psl/parser-database/src/walkers/index.rs b/psl/parser-database/src/walkers/index.rs index 63b6b30b7b44..0943b11e97ed 100644 --- a/psl/parser-database/src/walkers/index.rs +++ b/psl/parser-database/src/walkers/index.rs @@ -81,8 +81,8 @@ impl<'db> IndexWalker<'db> { .arguments .arguments .iter() - .find(|arg| match &arg.name { - Some(ident) if ident.name.is_empty() || ident.name == "fields" => true, + .find(|arg| match arg.name() { + Some(name) if name.is_empty() || name == "fields" => true, None => true, Some(_) => false, }) diff --git a/psl/psl-core/src/builtin_connectors/cockroach_datamodel_connector.rs b/psl/psl-core/src/builtin_connectors/cockroach_datamodel_connector.rs index 0bb972c8b9fa..a55a1a035129 100644 --- a/psl/psl-core/src/builtin_connectors/cockroach_datamodel_connector.rs +++ b/psl/psl-core/src/builtin_connectors/cockroach_datamodel_connector.rs @@ -2,6 +2,7 @@ mod native_types; mod validations; pub use native_types::CockroachType; +use schema_ast::ast::WithSpan; use crate::{ datamodel_connector::{ @@ -370,7 +371,7 @@ impl SequenceFunction { let mut this = SequenceFunction::default(); for arg in &args.arguments { - match arg.name.as_ref().map(|arg| arg.name.as_str()) { + match arg.name() { Some("virtual") => this.r#virtual = coerce::boolean(&arg.value, diagnostics), Some("cache") => this.cache = coerce::integer(&arg.value, diagnostics), Some("increment") => this.increment = coerce::integer(&arg.value, diagnostics), @@ -379,7 +380,7 @@ impl SequenceFunction { Some("start") => this.start = coerce::integer(&arg.value, diagnostics), Some(_) | None => diagnostics.push_error(DatamodelError::new_static( "Unexpected argument in `sequence()` function call", - arg.span, + arg.span(), )), } } diff --git a/psl/psl-core/src/builtin_connectors/cockroach_datamodel_connector/validations.rs b/psl/psl-core/src/builtin_connectors/cockroach_datamodel_connector/validations.rs index fc504d4f15ff..509a0d511b95 100644 --- a/psl/psl-core/src/builtin_connectors/cockroach_datamodel_connector/validations.rs +++ b/psl/psl-core/src/builtin_connectors/cockroach_datamodel_connector/validations.rs @@ -1,3 +1,5 @@ +use schema_ast::ast::WithSpan; + use crate::{ diagnostics::{DatamodelError, Diagnostics}, parser_database::{ @@ -25,7 +27,7 @@ pub(super) fn inverted_index_validations(index: IndexWalker<'_>, errors: &mut Di errors.push_error(DatamodelError::new_attribute_validation_error( msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); return; @@ -38,7 +40,7 @@ pub(super) fn inverted_index_validations(index: IndexWalker<'_>, errors: &mut Di errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } @@ -47,7 +49,7 @@ pub(super) fn inverted_index_validations(index: IndexWalker<'_>, errors: &mut Di errors.push_error(DatamodelError::new_attribute_validation_error( msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -63,7 +65,7 @@ pub(super) fn autoincrement_validations(model: ModelWalker<'_>, errors: &mut Dia errors.push_error(DatamodelError::new_attribute_validation_error( "The `autoincrement()` default function is defined only on BigInt fields on CockroachDB. Use sequence() if you want an autoincrementing Int field.", "default", - default_value.ast_attribute().span, + default_value.ast_attribute().span(), )); } } diff --git a/psl/psl-core/src/builtin_connectors/mssql_datamodel_connector/validations.rs b/psl/psl-core/src/builtin_connectors/mssql_datamodel_connector/validations.rs index 345eb3d9de7a..381230c419d4 100644 --- a/psl/psl-core/src/builtin_connectors/mssql_datamodel_connector/validations.rs +++ b/psl/psl-core/src/builtin_connectors/mssql_datamodel_connector/validations.rs @@ -1,3 +1,5 @@ +use schema_ast::ast::WithSpan; + use super::MsSqlType; use crate::{ datamodel_connector::{walker_ext_traits::ScalarFieldWalkerExt, Connector}, @@ -28,9 +30,9 @@ pub(crate) fn index_uses_correct_field_types( let error = connector.native_instance_error(&native_type); if index.is_unique() { - errors.push_error(error.new_incompatible_native_type_with_unique("", index.ast_attribute().span)) + errors.push_error(error.new_incompatible_native_type_with_unique("", index.ast_attribute().span())) } else { - errors.push_error(error.new_incompatible_native_type_with_index("", index.ast_attribute().span)) + errors.push_error(error.new_incompatible_native_type_with_index("", index.ast_attribute().span())) }; break; @@ -43,7 +45,7 @@ pub(crate) fn primary_key_uses_correct_field_types( errors: &mut Diagnostics, ) { for field in pk.fields() { - let span = pk.ast_attribute().span; + let span = pk.ast_attribute().span(); if let Some(native_type) = field.native_type_instance(connector) { let r#type: &MsSqlType = native_type.downcast_ref(); diff --git a/psl/psl-core/src/builtin_connectors/mysql_datamodel_connector/validations.rs b/psl/psl-core/src/builtin_connectors/mysql_datamodel_connector/validations.rs index e63351335830..c0c427a43c24 100644 --- a/psl/psl-core/src/builtin_connectors/mysql_datamodel_connector/validations.rs +++ b/psl/psl-core/src/builtin_connectors/mysql_datamodel_connector/validations.rs @@ -51,11 +51,11 @@ pub(crate) fn field_types_can_be_used_in_an_index( let error = if index.is_unique() { connector .native_instance_error(&native_type) - .new_incompatible_native_type_with_unique(LENGTH_GUIDE, index.ast_attribute().span) + .new_incompatible_native_type_with_unique(LENGTH_GUIDE, index.ast_attribute().span()) } else { connector .native_instance_error(&native_type) - .new_incompatible_native_type_with_index(LENGTH_GUIDE, index.ast_attribute().span) + .new_incompatible_native_type_with_index(LENGTH_GUIDE, index.ast_attribute().span()) }; errors.push_error(error); @@ -84,7 +84,7 @@ pub(crate) fn field_types_can_be_used_in_a_primary_key( continue; } - let span = primary_key.ast_attribute().span; + let span = primary_key.ast_attribute().span(); let error = connector .native_instance_error(&native_type) diff --git a/psl/psl-core/src/builtin_connectors/postgres_datamodel_connector/datasource.rs b/psl/psl-core/src/builtin_connectors/postgres_datamodel_connector/datasource.rs index b208548d5d6c..afc1e6105176 100644 --- a/psl/psl-core/src/builtin_connectors/postgres_datamodel_connector/datasource.rs +++ b/psl/psl-core/src/builtin_connectors/postgres_datamodel_connector/datasource.rs @@ -1,3 +1,5 @@ +use schema_ast::ast::WithSpan; + use super::{PostgresExtension, PostgresExtensions}; use crate::{ datamodel_connector::EXTENSIONS_KEY, @@ -48,23 +50,23 @@ fn filter_args<'a>( let mut dups = HashSet::new(); args.iter() - .filter_map(|arg| match arg.name.as_ref() { - Some(name) if dups.contains(name.name.as_str()) => { + .filter_map(|arg| match arg.name() { + Some(name) if dups.contains(name) => { diagnostics.push_error(DatamodelError::new_validation_error( - &format!("The argument `{}` can only be defined once", name.name), - arg.span, + &format!("The argument `{}` can only be defined once", name), + arg.span(), )); None } Some(name) => { - dups.insert(name.name.as_str()); - Some((name.name.as_str(), (arg.span, coerce::string(&arg.value, diagnostics)))) + dups.insert(name); + Some((name, (arg.span(), coerce::string(&arg.value, diagnostics)))) } None => { diagnostics.push_error(DatamodelError::new_validation_error( "The argument must have a name", - arg.span, + arg.span(), )); None diff --git a/psl/psl-core/src/builtin_connectors/postgres_datamodel_connector/validations.rs b/psl/psl-core/src/builtin_connectors/postgres_datamodel_connector/validations.rs index d6acef241311..fdec7084d1f4 100644 --- a/psl/psl-core/src/builtin_connectors/postgres_datamodel_connector/validations.rs +++ b/psl/psl-core/src/builtin_connectors/postgres_datamodel_connector/validations.rs @@ -42,7 +42,7 @@ pub(super) fn spgist_indexed_column_count(index: IndexWalker<'_>, errors: &mut D errors.push_error(DatamodelError::new_attribute_validation_error( "SpGist does not support multi-column indices.", index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } @@ -80,7 +80,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); continue; @@ -99,7 +99,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } (Some(native_type), None) => { @@ -108,7 +108,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } (None, Some(opclass)) => { @@ -120,7 +120,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } _ => { @@ -131,7 +131,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -165,7 +165,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -190,7 +190,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } _ => err_f(native_type_name, opclass), @@ -214,7 +214,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -267,7 +267,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -303,7 +303,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -326,7 +326,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -349,7 +349,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -377,7 +377,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -402,7 +402,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -425,7 +425,7 @@ pub(super) fn generalized_index_validations( errors.push_error(DatamodelError::new_attribute_validation_error( &msg, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } diff --git a/psl/psl-core/src/reformat.rs b/psl/psl-core/src/reformat.rs index c9e2bfafc49e..742eb35ce6fc 100644 --- a/psl/psl-core/src/reformat.rs +++ b/psl/psl-core/src/reformat.rs @@ -153,13 +153,13 @@ fn push_inline_relation_missing_arguments( let extra_args = extra_args.join(", "); let (prefix, suffix, position) = if relation_attribute.arguments.arguments.is_empty() { - ("(", ")", relation_attribute.span.end) + ("(", ")", relation_attribute.span().end) } else { - (", ", "", relation_attribute.span.end - 1) + (", ", "", relation_attribute.span().end - 1) }; ctx.add_missing_bit( - relation_attribute.span.file_id, + relation_attribute.span().file_id, MissingBit { position, content: format!("{prefix}{extra_args}{suffix}"), diff --git a/psl/psl-core/src/validate/generator_loader.rs b/psl/psl-core/src/validate/generator_loader.rs index ecd1ae1975c1..1505a3257cdf 100644 --- a/psl/psl-core/src/validate/generator_loader.rs +++ b/psl/psl-core/src/validate/generator_loader.rs @@ -35,7 +35,7 @@ pub(crate) fn load_generators_from_ast(ast_schema: &ast::SchemaAst, diagnostics: } fn lift_generator(ast_generator: &ast::GeneratorConfig, diagnostics: &mut Diagnostics) -> Option { - let generator_name = ast_generator.name.name.as_str(); + let generator_name = ast_generator.name(); let args: HashMap<_, &Expression> = ast_generator .properties .iter() @@ -70,7 +70,7 @@ fn lift_generator(ast_generator: &ast::GeneratorConfig, diagnostics: &mut Diagno None => { diagnostics.push_error(DatamodelError::new_generator_argument_not_found_error( PROVIDER_KEY, - &ast_generator.name.name, + ast_generator.name(), ast_generator.span(), )); return None; @@ -117,7 +117,7 @@ fn lift_generator(ast_generator: &ast::GeneratorConfig, diagnostics: &mut Diagno } Some(Generator { - name: ast_generator.name.name.clone(), + name: ast_generator.name().to_owned(), provider, output, binary_targets, diff --git a/psl/psl-core/src/validate/validation_pipeline/validations.rs b/psl/psl-core/src/validate/validation_pipeline/validations.rs index 76e277be7394..0334bcfc6b32 100644 --- a/psl/psl-core/src/validate/validation_pipeline/validations.rs +++ b/psl/psl-core/src/validate/validation_pipeline/validations.rs @@ -18,6 +18,7 @@ use crate::datamodel_connector::ConnectorCapability; use super::context::Context; use names::Names; use parser_database::walkers::RefinedRelationWalker; +use schema_ast::ast::WithSpan; pub(super) fn validate(ctx: &mut Context<'_>) { let names = Names::new(ctx); @@ -73,7 +74,7 @@ pub(super) fn validate(ctx: &mut Context<'_>) { if let Some(pk) = model.primary_key() { for field_attribute in pk.scalar_field_attributes() { - let span = pk.ast_attribute().span; + let span = pk.ast_attribute().span(); let attribute = (pk.attribute_name(), span); fields::validate_length_used_with_correct_types(field_attribute, attribute, ctx); } @@ -128,7 +129,7 @@ pub(super) fn validate(ctx: &mut Context<'_>) { indexes::composite_type_in_compound_unique_index(index, ctx); for field_attribute in index.scalar_field_attributes() { - let span = index.ast_attribute().span; + let span = index.ast_attribute().span(); let attribute = (index.attribute_name(), span); fields::validate_length_used_with_correct_types(field_attribute, attribute, ctx); diff --git a/psl/psl-core/src/validate/validation_pipeline/validations/autoincrement.rs b/psl/psl-core/src/validate/validation_pipeline/validations/autoincrement.rs index cf5171c82852..b71d51db25a9 100644 --- a/psl/psl-core/src/validate/validation_pipeline/validations/autoincrement.rs +++ b/psl/psl-core/src/validate/validation_pipeline/validations/autoincrement.rs @@ -21,7 +21,7 @@ pub(super) fn validate_auto_increment(model: ModelWalker<'_>, ctx: &mut Context< ctx.push_error(DatamodelError::new_attribute_validation_error( msg, "@default", - field.default_attribute().unwrap().span, + field.default_attribute().unwrap().span(), )); } diff --git a/psl/psl-core/src/validate/validation_pipeline/validations/composite_types.rs b/psl/psl-core/src/validate/validation_pipeline/validations/composite_types.rs index fbaaa3525a49..7521bbc1c0fa 100644 --- a/psl/psl-core/src/validate/validation_pipeline/validations/composite_types.rs +++ b/psl/psl-core/src/validate/validation_pipeline/validations/composite_types.rs @@ -112,7 +112,7 @@ pub(super) fn validate_default_value(field: CompositeTypeFieldWalker<'_>, ctx: & ctx.push_error(DatamodelError::new_attribute_validation_error( "A `map` argument for the default value of a field on a composite type is not allowed. Consider removing it.", "@default", - default_attribute.unwrap().span, + default_attribute.unwrap().span(), )); } diff --git a/psl/psl-core/src/validate/validation_pipeline/validations/database_name.rs b/psl/psl-core/src/validate/validation_pipeline/validations/database_name.rs index 116b31a2532d..76ac50044c06 100644 --- a/psl/psl-core/src/validate/validation_pipeline/validations/database_name.rs +++ b/psl/psl-core/src/validate/validation_pipeline/validations/database_name.rs @@ -1,3 +1,5 @@ +use schema_ast::ast::{WithName, WithSpan}; + use crate::{ast, validate::validation_pipeline::context::Context}; pub(super) fn validate_db_name( @@ -9,10 +11,10 @@ pub(super) fn validate_db_name( double_at: bool, ) { if let Some(err) = crate::datamodel_connector::constraint_names::ConstraintNames::is_db_name_too_long( - attribute.span, + attribute.span(), model_name, db_name, - &attribute.name.name, + attribute.name(), ctx.connector, double_at, ) { diff --git a/psl/psl-core/src/validate/validation_pipeline/validations/fields.rs b/psl/psl-core/src/validate/validation_pipeline/validations/fields.rs index 674d8e50d3bc..8a9202841574 100644 --- a/psl/psl-core/src/validate/validation_pipeline/validations/fields.rs +++ b/psl/psl-core/src/validate/validation_pipeline/validations/fields.rs @@ -229,7 +229,7 @@ pub(super) fn validate_default_value(field: ScalarFieldWalker<'_>, ctx: &mut Con ctx.push_error(DatamodelError::new_attribute_validation_error( msg, "@default", - default_attribute.unwrap().span, + default_attribute.unwrap().span(), )); } diff --git a/psl/psl-core/src/validate/validation_pipeline/validations/indexes.rs b/psl/psl-core/src/validate/validation_pipeline/validations/indexes.rs index e9bae626f374..5893497a1e06 100644 --- a/psl/psl-core/src/validate/validation_pipeline/validations/indexes.rs +++ b/psl/psl-core/src/validate/validation_pipeline/validations/indexes.rs @@ -7,6 +7,7 @@ use crate::{ }; use itertools::Itertools; use parser_database::{walkers::IndexWalker, IndexAlgorithm}; +use schema_ast::ast::WithSpan; /// Different databases validate index and unique constraint names in a certain namespace. /// Validates index and unique constraint names against the database requirements. @@ -30,7 +31,7 @@ pub(super) fn has_a_unique_constraint_name(index: IndexWalker<'_>, names: &super .span_for_argument("map") .or_else(|| index.ast_attribute().span_for_argument("name")); - let span = from_arg.unwrap_or(index.ast_attribute().span); + let span = from_arg.unwrap_or(index.ast_attribute().span()); ctx.push_error(DatamodelError::new_attribute_validation_error( &message, @@ -59,7 +60,7 @@ pub(super) fn unique_index_has_a_unique_custom_name_per_model( ); let from_arg = index.ast_attribute().span_for_argument("name"); - let span = from_arg.unwrap_or(index.ast_attribute().span); + let span = from_arg.unwrap_or(index.ast_attribute().span()); ctx.push_error(DatamodelError::new_attribute_validation_error( &message, @@ -82,7 +83,7 @@ pub(crate) fn field_length_prefix_supported(index: IndexWalker<'_>, ctx: &mut Co ctx.push_error(DatamodelError::new_attribute_validation_error( message, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -99,7 +100,7 @@ pub(crate) fn fulltext_index_preview_feature_enabled(index: IndexWalker<'_>, ctx ctx.push_error(DatamodelError::new_attribute_validation_error( message, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -116,7 +117,7 @@ pub(crate) fn fulltext_index_supported(index: IndexWalker<'_>, ctx: &mut Context ctx.push_error(DatamodelError::new_attribute_validation_error( message, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -141,7 +142,7 @@ pub(crate) fn fulltext_columns_should_not_define_length(index: IndexWalker<'_>, ctx.push_error(DatamodelError::new_attribute_validation_error( message, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -170,7 +171,7 @@ pub(crate) fn fulltext_column_sort_is_supported(index: IndexWalker<'_>, ctx: &mu ctx.push_error(DatamodelError::new_attribute_validation_error( message, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -223,7 +224,7 @@ pub(crate) fn fulltext_text_columns_should_be_bundled_together(index: IndexWalke ctx.push_error(DatamodelError::new_attribute_validation_error( message, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); return; @@ -248,7 +249,7 @@ pub(crate) fn hash_index_must_not_use_sort_param(index: IndexWalker<'_>, ctx: &m ctx.push_error(DatamodelError::new_attribute_validation_error( message, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -271,7 +272,7 @@ pub(super) fn has_fields(index: IndexWalker<'_>, ctx: &mut Context<'_>) { ctx.push_error(DatamodelError::new_attribute_validation_error( "The list of fields in an index cannot be empty. Please specify at least one field.", index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )) } @@ -287,7 +288,7 @@ pub(crate) fn supports_clustering_setting(index: IndexWalker<'_>, ctx: &mut Cont ctx.push_error(DatamodelError::new_attribute_validation_error( "Defining clustering is not supported in the current connector.", index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )) } @@ -305,7 +306,7 @@ pub(crate) fn clustering_can_be_defined_only_once(index: IndexWalker<'_>, ctx: & ctx.push_error(DatamodelError::new_attribute_validation_error( "A model can only hold one clustered index or key.", index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -322,7 +323,7 @@ pub(crate) fn clustering_can_be_defined_only_once(index: IndexWalker<'_>, ctx: & ctx.push_error(DatamodelError::new_attribute_validation_error( "A model can only hold one clustered index.", index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); return; @@ -345,7 +346,7 @@ pub(crate) fn index_algorithm_is_supported(index: IndexWalker<'_>, ctx: &mut Con let span = index .ast_attribute() .span_for_argument("type") - .unwrap_or_else(|| index.ast_attribute().span); + .unwrap_or_else(|| index.ast_attribute().span()); ctx.push_error(DatamodelError::new_attribute_validation_error( message, @@ -370,7 +371,7 @@ pub(crate) fn opclasses_are_not_allowed_with_other_than_normal_indices(index: In ctx.push_error(DatamodelError::new_attribute_validation_error( message, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); return; @@ -394,7 +395,7 @@ pub(crate) fn composite_type_in_compound_unique_index(index: IndexWalker<'_>, ct ctx.push_error(DatamodelError::new_attribute_validation_error( &message, index.attribute_name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } @@ -424,7 +425,7 @@ pub(super) fn unique_client_name_does_not_clash_with_field(index: IndexWalker<'_ &format!("The field `{idx_client_name}` clashes with the `{attr_name}` name. Please resolve the conflict by providing a custom id name: `{attr_name}([...], name: \"custom_name\")`"), container_type, index.model().name(), - index.ast_attribute().span, + index.ast_attribute().span(), )); } } diff --git a/psl/psl-core/src/validate/validation_pipeline/validations/models.rs b/psl/psl-core/src/validate/validation_pipeline/validations/models.rs index a53063624b2d..6cde92463db2 100644 --- a/psl/psl-core/src/validate/validation_pipeline/validations/models.rs +++ b/psl/psl-core/src/validate/validation_pipeline/validations/models.rs @@ -7,6 +7,7 @@ use crate::{ PreviewFeature, }; use parser_database::walkers::{ModelWalker, PrimaryKeyWalker}; +use schema_ast::ast::WithAttributes; use std::{borrow::Cow, collections::HashMap}; /// A model must have either a primary key, or a unique criterion @@ -89,7 +90,7 @@ pub(super) fn has_a_unique_primary_key_name(model: ModelWalker<'_>, names: &supe let span = pk .ast_attribute() .span_for_argument("map") - .unwrap_or_else(|| pk.ast_attribute().span); + .unwrap_or_else(|| pk.ast_attribute().span()); ctx.push_error(DatamodelError::new_attribute_validation_error( &message, @@ -123,7 +124,7 @@ pub(super) fn has_a_unique_custom_primary_key_name_per_model( let span = pk .ast_attribute() .span_for_argument("name") - .unwrap_or_else(|| pk.ast_attribute().span); + .unwrap_or_else(|| pk.ast_attribute().span()); ctx.push_error(DatamodelError::new_attribute_validation_error( &message, @@ -143,7 +144,7 @@ pub(crate) fn primary_key_length_prefix_supported(model: ModelWalker<'_>, ctx: & if let Some(pk) = model.primary_key() { if pk.scalar_field_attributes().any(|f| f.length().is_some()) { let message = "The length argument is not supported in the primary key with the current connector"; - let span = pk.ast_attribute().span; + let span = pk.ast_attribute().span(); ctx.push_error(DatamodelError::new_attribute_validation_error( message, @@ -163,7 +164,7 @@ pub(crate) fn primary_key_sort_order_supported(model: ModelWalker<'_>, ctx: &mut if let Some(pk) = model.primary_key() { if pk.scalar_field_attributes().any(|f| f.sort_order().is_some()) { let message = "The sort argument is not supported in the primary key with the current connector"; - let span = pk.ast_attribute().span; + let span = pk.ast_attribute().span(); ctx.push_error(DatamodelError::new_attribute_validation_error( message, @@ -190,7 +191,7 @@ pub(crate) fn only_one_fulltext_attribute_allowed(model: ModelWalker<'_>, ctx: & let spans = model .indexes() .filter(|i| i.is_fulltext()) - .map(|i| i.ast_attribute().span) + .map(|i| i.ast_attribute().span()) .collect::>(); if spans.len() > 1 { @@ -230,7 +231,7 @@ pub(crate) fn primary_key_connector_specific(model: ModelWalker<'_>, ctx: &mut C "The current connector does not support compound ids.", container_type, model.name(), - primary_key.ast_attribute().span, + primary_key.ast_attribute().span(), )); } } @@ -249,7 +250,7 @@ pub(super) fn id_has_fields(model: ModelWalker<'_>, ctx: &mut Context<'_>) { ctx.push_error(DatamodelError::new_attribute_validation_error( "The list of fields in an `@@id()` attribute cannot be empty. Please specify at least one field.", id.attribute_name(), - id.ast_attribute().span, + id.ast_attribute().span(), )) } @@ -269,7 +270,7 @@ pub(super) fn id_client_name_does_not_clash_with_field(model: ModelWalker<'_>, c &format!("The field `{id_client_name}` clashes with the `@@id` attribute's name. Please resolve the conflict by providing a custom id name: `@@id([...], name: \"custom_name\")`"), container_type, model.name(), - id.ast_attribute().span, + id.ast_attribute().span(), )); } } @@ -373,7 +374,7 @@ pub(super) fn database_name_clashes(ctx: &mut Context<'_>) { let existing_model_name = &ctx.db.ast(existing.0)[existing.1].name(); let attribute = model .ast_model() - .attributes + .attributes() .iter() .find(|attr| attr.name() == "map") .unwrap(); @@ -387,7 +388,7 @@ pub(super) fn database_name_clashes(ctx: &mut Context<'_>) { Some(existing) => { let existing_model = &ctx.db.ast(existing.0)[existing.1]; let attribute = existing_model - .attributes + .attributes() .iter() .find(|attr| attr.name() == "map") .unwrap(); diff --git a/psl/psl-core/src/validate/validation_pipeline/validations/relation_fields.rs b/psl/psl-core/src/validate/validation_pipeline/validations/relation_fields.rs index 58334a3ae2b4..4aef1b371c65 100644 --- a/psl/psl-core/src/validate/validation_pipeline/validations/relation_fields.rs +++ b/psl/psl-core/src/validate/validation_pipeline/validations/relation_fields.rs @@ -12,6 +12,7 @@ use parser_database::{ walkers::{ModelWalker, RelationFieldId, RelationFieldWalker, RelationName}, ReferentialAction, }; +use schema_ast::ast::WithAttributes; use std::fmt; struct Fields<'db> { @@ -246,7 +247,7 @@ pub(super) fn map(field: RelationFieldWalker<'_>, ctx: &mut Context<'_>) { if let Some(relation_attr) = field .ast_field() - .attributes + .attributes() .iter() .find(|attr| attr.name() == "relation") { diff --git a/psl/psl-core/src/validate/validation_pipeline/validations/relations.rs b/psl/psl-core/src/validate/validation_pipeline/validations/relations.rs index e834fe3b54ea..c1a48731a29b 100644 --- a/psl/psl-core/src/validate/validation_pipeline/validations/relations.rs +++ b/psl/psl-core/src/validate/validation_pipeline/validations/relations.rs @@ -109,7 +109,7 @@ pub(super) fn same_length_in_referencing_and_referenced(relation: InlineRelation (Some(fields), Some(references)) if fields.len() != references.len() => { ctx.push_error(DatamodelError::new_validation_error( "You must specify the same number of fields in `fields` and `references`.", - relation_field.relation_attribute().unwrap().span, + relation_field.relation_attribute().unwrap().span(), )); } _ => (), diff --git a/psl/schema-ast/src/ast/argument.rs b/psl/schema-ast/src/ast/argument.rs index 8222806e1e16..bfc81ea19bf3 100644 --- a/psl/schema-ast/src/ast/argument.rs +++ b/psl/schema-ast/src/ast/argument.rs @@ -1,4 +1,4 @@ -use super::{Expression, Identifier, Span, WithSpan}; +use super::{Expression, Identifier, Span, WithIdentifier, WithSpan}; use std::fmt::{Display, Formatter}; /// A list of arguments inside parentheses. @@ -93,5 +93,11 @@ impl WithSpan for Argument { /// for autocompletion. #[derive(Debug, Clone)] pub struct EmptyArgument { - pub name: Identifier, + pub(crate) name: Identifier, +} + +impl WithIdentifier for EmptyArgument { + fn identifier(&self) -> &Identifier { + &self.name + } } diff --git a/psl/schema-ast/src/ast/attribute.rs b/psl/schema-ast/src/ast/attribute.rs index f664e4da2c5e..e5aa57410fdd 100644 --- a/psl/schema-ast/src/ast/attribute.rs +++ b/psl/schema-ast/src/ast/attribute.rs @@ -11,7 +11,7 @@ pub struct Attribute { /// @@index([a, b, c]) /// ^^^^^ /// ``` - pub name: Identifier, + pub(crate) name: Identifier, /// The arguments of the attribute. /// /// ```ignore @@ -20,7 +20,7 @@ pub struct Attribute { /// ``` pub arguments: ArgumentsList, /// The AST span of the node. - pub span: Span, + pub(crate) span: Span, } impl Attribute { diff --git a/psl/schema-ast/src/ast/enum.rs b/psl/schema-ast/src/ast/enum.rs index 990e599d0e7f..b922bb75ac12 100644 --- a/psl/schema-ast/src/ast/enum.rs +++ b/psl/schema-ast/src/ast/enum.rs @@ -111,7 +111,7 @@ impl WithDocumentation for Enum { #[derive(Debug, Clone)] pub struct EnumValue { /// The name of the enum value as it will be exposed by the api. - pub name: Identifier, + pub(crate) name: Identifier, /// The attributes of this value. /// /// ```ignore diff --git a/psl/schema-ast/src/ast/field.rs b/psl/schema-ast/src/ast/field.rs index 394381a2f3b1..4c55d30bbce1 100644 --- a/psl/schema-ast/src/ast/field.rs +++ b/psl/schema-ast/src/ast/field.rs @@ -29,7 +29,7 @@ pub struct Field { /// name String @id @default("lol") /// ^^^^^^^^^^^^^^^^^^^ /// ``` - pub attributes: Vec, + pub(crate) attributes: Vec, /// The comments for this field. /// /// ```ignore diff --git a/psl/schema-ast/src/ast/find_at_position/model.rs b/psl/schema-ast/src/ast/find_at_position/model.rs index a88a7b2ba25b..132270359fa4 100644 --- a/psl/schema-ast/src/ast/find_at_position/model.rs +++ b/psl/schema-ast/src/ast/find_at_position/model.rs @@ -1,4 +1,4 @@ -use super::{AttributePosition, FieldPosition, WithName, WithSpan}; +use super::{AttributePosition, FieldPosition, WithIdentifier, WithName, WithSpan}; use crate::ast::{self}; @@ -40,7 +40,7 @@ pub enum ModelPosition<'ast> { impl<'ast> ModelPosition<'ast> { pub(crate) fn new(model: &'ast ast::Model, position: usize) -> Self { - if model.name.span.contains(position) { + if model.identifier().span().contains(position) { return ModelPosition::Name(model.name()); } @@ -52,7 +52,7 @@ impl<'ast> ModelPosition<'ast> { for (attr_id, attr) in model.attributes.iter().enumerate() { if attr.span().contains(position) { - return ModelPosition::ModelAttribute(&attr.name.name, attr_id, AttributePosition::new(attr, position)); + return ModelPosition::ModelAttribute(attr.name(), attr_id, AttributePosition::new(attr, position)); } } diff --git a/psl/schema-ast/src/ast/find_at_position/property.rs b/psl/schema-ast/src/ast/find_at_position/property.rs index 245ced4ba294..1abf2c0df4cf 100644 --- a/psl/schema-ast/src/ast/find_at_position/property.rs +++ b/psl/schema-ast/src/ast/find_at_position/property.rs @@ -49,9 +49,10 @@ impl<'ast> PropertyPosition<'ast> { } } } + if property.span.contains(position) && !property.name.span.contains(position) { // TODO(@druue): this should actually just return the value string, not the name of the property the value is for - return PropertyPosition::Value(&property.name.name); + return PropertyPosition::Value(property.name()); } PropertyPosition::Property diff --git a/psl/schema-ast/src/ast/identifier.rs b/psl/schema-ast/src/ast/identifier.rs index 92eccefecf1a..84aa0f2572b2 100644 --- a/psl/schema-ast/src/ast/identifier.rs +++ b/psl/schema-ast/src/ast/identifier.rs @@ -1,13 +1,13 @@ -use super::{Span, WithSpan}; +use super::{Span, WithName, WithSpan}; use diagnostics::FileId; /// An identifier. #[derive(Debug, Clone, PartialEq)] pub struct Identifier { /// The identifier contents. - pub name: String, + pub(crate) name: String, /// The span of the AST node. - pub span: Span, + pub(crate) span: Span, } impl Identifier { @@ -19,6 +19,12 @@ impl Identifier { } } +impl WithName for Identifier { + fn name(&self) -> &str { + &self.name + } +} + impl WithSpan for Identifier { fn span(&self) -> Span { self.span diff --git a/psl/schema-ast/src/ast/model.rs b/psl/schema-ast/src/ast/model.rs index 4df12a95ced6..94742ae3dff2 100644 --- a/psl/schema-ast/src/ast/model.rs +++ b/psl/schema-ast/src/ast/model.rs @@ -54,7 +54,7 @@ pub struct Model { /// ^^^^^^^^^^^^ /// } /// ``` - pub attributes: Vec, + pub(crate) attributes: Vec, /// The documentation for this model. /// /// ```ignore