Parse optional ingested file annotation

This commit is contained in:
Agus Zubiaga 2024-05-03 08:42:43 -03:00
parent f7011c8e33
commit fe2eb0f0a5
No known key found for this signature in database
3 changed files with 51 additions and 15 deletions

View file

@ -1,5 +1,6 @@
use std::fmt::Debug;
use crate::expr::merge_spaces;
use crate::header::{
self, AppHeader, HostedHeader, ModuleHeader, ModuleName, PackageHeader, PlatformHeader,
};
@ -162,6 +163,8 @@ impl<'a> Module<'a> {
Self::header_import_to_value_def(None, name, exposed, import.region)
}
header::ImportsEntry::IngestedFile(path, typed_ident) => {
let typed_ident = typed_ident.extract_spaces();
ValueDef::IngestedFileImport(IngestedFileImport {
before_path: &[],
path: Loc {
@ -174,11 +177,16 @@ impl<'a> Module<'a> {
item: ImportAsKeyword,
after: &[],
},
item: Loc {
value: typed_ident,
region: import.region,
},
item: typed_ident.item.ident,
},
annotation: Some(IngestedFileAnnotation {
before_colon: merge_spaces(
arena,
typed_ident.before,
typed_ident.item.spaces_before_colon,
),
annotation: typed_ident.item.ann,
}),
})
}
};
@ -1052,7 +1060,20 @@ pub struct ModuleImport<'a> {
pub struct IngestedFileImport<'a> {
pub before_path: &'a [CommentOrNewline<'a>],
pub path: Loc<StrLiteral<'a>>,
pub name: header::KeywordItem<'a, ImportAsKeyword, Loc<Spaced<'a, header::TypedIdent<'a>>>>,
pub name: header::KeywordItem<'a, ImportAsKeyword, Loc<&'a str>>,
pub annotation: Option<IngestedFileAnnotation<'a>>,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct IngestedFileAnnotation<'a> {
pub before_colon: &'a [CommentOrNewline<'a>],
pub annotation: Loc<TypeAnnotation<'a>>,
}
impl<'a> Malformed for IngestedFileAnnotation<'a> {
fn is_malformed(&self) -> bool {
self.annotation.value.is_malformed()
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
@ -2621,7 +2642,8 @@ impl<'a> Malformed for ValueDef<'a> {
before_path: _,
path,
name: _,
}) => path.is_malformed(),
annotation,
}) => path.is_malformed() || annotation.is_malformed(),
ValueDef::Stmt(loc_expr) => loc_expr.is_malformed(),
}
}

View file

@ -1,8 +1,8 @@
use crate::ast::{
is_expr_suffixed, AssignedField, Collection, CommentOrNewline, Defs, Expr, ExtractSpaces,
Implements, ImplementsAbilities, ImportAlias, ImportAsKeyword, ImportExposingKeyword,
ImportedModuleName, IngestedFileImport, ModuleImport, Pattern, RecordBuilderField, Spaceable,
Spaced, Spaces, TypeAnnotation, TypeDef, TypeHeader, ValueDef,
ImportedModuleName, IngestedFileAnnotation, IngestedFileImport, ModuleImport, Pattern,
RecordBuilderField, Spaceable, Spaced, Spaces, TypeAnnotation, TypeDef, TypeHeader, ValueDef,
};
use crate::blankspace::{
space0_after_e, space0_around_e_no_after_indent_check, space0_around_ee, space0_before_e,
@ -1050,17 +1050,15 @@ fn import_ingested_file_body<'a>() -> impl Parser<'a, ValueDef<'a>, EImport<'a>>
string_literal::parse_str_literal()
)),
name: import_ingested_file_as(),
annotation: optional(backtrackable(import_ingested_file_annotation()))
}),
ValueDef::IngestedFileImport
)
}
#[inline(always)]
fn import_ingested_file_as<'a>() -> impl Parser<
'a,
header::KeywordItem<'a, ImportAsKeyword, Loc<Spaced<'a, header::TypedIdent<'a>>>>,
EImport<'a>,
> {
fn import_ingested_file_as<'a>(
) -> impl Parser<'a, header::KeywordItem<'a, ImportAsKeyword, Loc<&'a str>>, EImport<'a>> {
record!(header::KeywordItem {
keyword: module::spaces_around_keyword(
ImportAsKeyword,
@ -1068,7 +1066,19 @@ fn import_ingested_file_as<'a>() -> impl Parser<
EImport::IndentAs,
EImport::IndentIngestedName
),
item: specialize_err(EImport::IngestedName, loc!(module::typed_ident()))
item: specialize_err(
|(), pos| EImport::IngestedName(pos),
loc!(lowercase_ident())
)
})
}
#[inline(always)]
fn import_ingested_file_annotation<'a>() -> impl Parser<'a, IngestedFileAnnotation<'a>, EImport<'a>>
{
record!(IngestedFileAnnotation {
before_colon: skip_second!(space0_e(EImport::IndentColon), byte(b':', EImport::Colon)),
annotation: specialize_err(EImport::Annotation, type_annotation::located(false))
})
}

View file

@ -542,7 +542,11 @@ pub enum EImport<'a> {
IndentIngestedPath(Position),
IngestedPath(Position),
IndentIngestedName(Position),
IngestedName(ETypedIdent<'a>, Position),
IngestedName(Position),
IndentColon(Position),
Colon(Position),
IndentAnnotation(Position),
Annotation(EType<'a>, Position),
Space(BadInputError, Position),
}