Skip to content

Commit 173c7ce

Browse files
author
ffonion
committed
feat(compiler): parse declared resource type keys
1 parent ae4020a commit 173c7ce

3 files changed

Lines changed: 40 additions & 1 deletion

File tree

‎src/compiler/parser/mod.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::builtins::{
1717
};
1818
use crate::compiler::modules::{UseDecl, UsePathSegment};
1919
use crate::compiler::source_map::{SourceId, Span};
20-
use crate::host_api::{HostApiCatalog, HostFunctionSchema};
20+
use crate::host_api::{HostApiCatalog, HostFunctionSchema, ResourceTypeKey};
2121

2222
pub(crate) use self::expressions::host_generic_type_arg_arity;
2323
use self::lexer::{Lexer, ParserFormatArg, Token, TokenKind, is_ident_continue, is_ident_start};

‎src/compiler/parser/statements.rs‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,24 @@ impl Parser {
966966
"bool" => TypeSchema::Bool,
967967
"string" => TypeSchema::String,
968968
"bytes" => TypeSchema::Bytes,
969+
"resource" => {
970+
self.expect(&TokenKind::Less, "expected '<' before resource type key")?;
971+
let mut key = self.expect_ident("expected resource type key")?;
972+
while self.match_kind(&TokenKind::Dot) {
973+
key.push('.');
974+
key.push_str(
975+
&self.expect_ident("expected resource type key segment after '.'")?,
976+
);
977+
}
978+
self.expect(&TokenKind::Greater, "expected '>' after resource type key")?;
979+
let key = ResourceTypeKey::new(key.clone()).map_err(|error| ParseError {
980+
span: Some(span),
981+
code: None,
982+
line: self.current_line(),
983+
message: format!("invalid resource type key '{key}': {error}"),
984+
})?;
985+
TypeSchema::Resource(key)
986+
}
969987
"array" => {
970988
if self.match_kind(&TokenKind::Less) {
971989
let element = self.parse_declared_type_schema()?;

‎tests/host_resource_type_inference_tests.rs‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,27 @@ fn default_analysis_resolves_standard_catalog_calls_and_annotations() {
686686
);
687687
}
688688

689+
#[test]
690+
fn declared_resource_type_parses_qualified_key_and_resolves_borrow_call() {
691+
let model = analyze_source_from_string_with_options(
692+
"resource_param.rss",
693+
r#"
694+
use sqlite;
695+
fn query(db: resource<sqlite.connection>) -> int {
696+
sqlite::query(&db, "SELECT 1")
697+
}
698+
"#,
699+
CompileSourceFileOptions::default().with_host_api_catalog(test_catalog()),
700+
)
701+
.expect("qualified resource type declaration should parse and analyze");
702+
703+
assert!(
704+
model.diagnostics().is_empty(),
705+
"declared resource parameter should resolve exactly: {:?}",
706+
model.diagnostics()
707+
);
708+
}
709+
689710
#[cfg(feature = "runtime")]
690711
#[test]
691712
fn explicit_analysis_catalog_is_not_augmented_by_standard_catalog() {

0 commit comments

Comments
 (0)