From 5069c1e45ecf2a360597011a6b0ea62f1de78b0b Mon Sep 17 00:00:00 2001 From: peefy Date: Tue, 7 May 2024 16:49:00 +0800 Subject: [PATCH] feat: top level variable back reference Signed-off-by: peefy --- VERSION | 2 +- kclvm/compiler/src/codegen/error.rs | 9 +-- kclvm/compiler/src/codegen/llvm/context.rs | 66 +++++++++++++++++- kclvm/compiler/src/codegen/llvm/module.rs | 4 +- kclvm/compiler/src/codegen/llvm/node.rs | 14 +++- kclvm/runtime/src/_kcl_run.rs | 15 ++-- kclvm/runtime/src/_kclvm.bc | Bin 14344 -> 14344 bytes kclvm/runtime/src/_kclvm.h | 2 +- kclvm/runtime/src/_kclvm.ll | 2 +- kclvm/runtime/src/_kclvm.rs | 2 +- kclvm/runtime/src/_kclvm_addr.rs | 2 +- kclvm/runtime/src/_kclvm_api_spec.rs | 6 +- kclvm/runtime/src/_kclvm_main_win.c | 18 ----- kclvm/runtime/src/context/api.rs | 2 +- kclvm/tools/src/testing/suite.rs | 4 +- .../schema/irrelevant_order/simple_10/main.k | 15 ++++ .../irrelevant_order/simple_10/stdout.golden | 6 ++ .../schema/irrelevant_order/simple_7/main.k | 2 + .../irrelevant_order/simple_7/stdout.golden | 2 + .../schema/irrelevant_order/simple_8/main.k | 3 + .../irrelevant_order/simple_8/stdout.golden | 3 + .../schema/irrelevant_order/simple_9/kcl.mod | 0 .../schema/irrelevant_order/simple_9/main.k | 3 + .../irrelevant_order/simple_9/pkg/base.k | 4 ++ .../irrelevant_order/simple_9/pkg/input.k | 5 ++ .../irrelevant_order/simple_9/pkg/versions.k | 3 + .../irrelevant_order/simple_9/stdout.golden | 4 ++ 27 files changed, 153 insertions(+), 45 deletions(-) delete mode 100644 kclvm/runtime/src/_kclvm_main_win.c create mode 100644 test/grammar/schema/irrelevant_order/simple_10/main.k create mode 100644 test/grammar/schema/irrelevant_order/simple_10/stdout.golden create mode 100644 test/grammar/schema/irrelevant_order/simple_7/main.k create mode 100644 test/grammar/schema/irrelevant_order/simple_7/stdout.golden create mode 100644 test/grammar/schema/irrelevant_order/simple_8/main.k create mode 100644 test/grammar/schema/irrelevant_order/simple_8/stdout.golden create mode 100644 test/grammar/schema/irrelevant_order/simple_9/kcl.mod create mode 100644 test/grammar/schema/irrelevant_order/simple_9/main.k create mode 100644 test/grammar/schema/irrelevant_order/simple_9/pkg/base.k create mode 100644 test/grammar/schema/irrelevant_order/simple_9/pkg/input.k create mode 100644 test/grammar/schema/irrelevant_order/simple_9/pkg/versions.k create mode 100644 test/grammar/schema/irrelevant_order/simple_9/stdout.golden diff --git a/VERSION b/VERSION index 35864a97f..ac39a106c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.8.7 \ No newline at end of file +0.9.0 diff --git a/kclvm/compiler/src/codegen/error.rs b/kclvm/compiler/src/codegen/error.rs index 4aa51b47d..dcf2b2406 100644 --- a/kclvm/compiler/src/codegen/error.rs +++ b/kclvm/compiler/src/codegen/error.rs @@ -3,11 +3,12 @@ use std::error; use std::fmt::{self, Debug}; -pub const VALUE_TYPE_NOT_FOUND_MSG: &str = "Type is not found"; -pub const CONTEXT_VAR_NOT_FOUND_MSG: &str = "Context variable is not found"; -pub const FUNCTION_RETURN_VALUE_NOT_FOUND_MSG: &str = "Function return value is not found"; -pub const COMPILE_ERROR_MSG: &str = "Compile error"; +pub const VALUE_TYPE_NOT_FOUND_MSG: &str = "Internal error, value type is not found"; +pub const CONTEXT_VAR_NOT_FOUND_MSG: &str = "Internal error, context variable is not found"; pub const INTERNAL_ERROR_MSG: &str = "Internal error, please report a bug to us"; +pub const FUNCTION_RETURN_VALUE_NOT_FOUND_MSG: &str = + "Internal error, function return value is not found"; +pub const COMPILE_ERROR_MSG: &str = "Compile error"; pub const CODE_GEN_ERROR_MSG: &str = "Code gen error"; pub const INVALID_OPERATOR_MSG: &str = "Invalid operator"; pub const INVALID_JOINED_STR_MSG: &str = "Invalid AST JoinedString value"; diff --git a/kclvm/compiler/src/codegen/llvm/context.rs b/kclvm/compiler/src/codegen/llvm/context.rs index 1f4459454..f1a60bac4 100644 --- a/kclvm/compiler/src/codegen/llvm/context.rs +++ b/kclvm/compiler/src/codegen/llvm/context.rs @@ -1311,8 +1311,10 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { let tpe = self.value_ptr_type().into_pointer_type(); let void_type = self.context.void_type(); let context_ptr_type = self.context_ptr_type(); - let fn_type = tpe.fn_type(&[context_ptr_type.into()], false); - let void_fn_type = void_type.fn_type(&[context_ptr_type.into()], false); + let scope_ptr_type = self.scope_ptr_type(); + let fn_type = tpe.fn_type(&[context_ptr_type.into(), scope_ptr_type.into()], false); + let void_fn_type = + void_type.fn_type(&[context_ptr_type.into(), scope_ptr_type.into()], false); let has_main_pkg = self.program.pkgs.contains_key(MAIN_PKG_PATH); let function = if self.no_link { let mut modules = self.modules.borrow_mut(); @@ -1756,6 +1758,18 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { let variables = last.variables.borrow(); if let Some(var) = variables.get(&name.to_string()) { self.builder.build_store(*var, value); + if save_scope { + self.build_void_call( + &ApiFunc::kclvm_scope_set.name(), + &[ + self.current_runtime_ctx_ptr(), + self.current_scope_ptr(), + self.native_global_string(¤t_pkgpath, "").into(), + self.native_global_string(name, "").into(), + value, + ], + ); + } existed = true; } } @@ -1766,6 +1780,18 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { let var_name = format!("${}.${}", pkgpath_without_prefix!(pkgpath), name); let pointer = self.new_global_kcl_value_ptr(&var_name); self.builder.build_store(pointer, value); + if save_scope { + self.build_void_call( + &ApiFunc::kclvm_scope_set.name(), + &[ + self.current_runtime_ctx_ptr(), + self.current_scope_ptr(), + self.native_global_string(¤t_pkgpath, "").into(), + self.native_global_string(name, "").into(), + value, + ], + ); + } if !variables.contains_key(name) { variables.insert(name.to_string(), pointer); } @@ -1993,7 +2019,41 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { } } } else { - self.builder.build_load(*var, name) + // Not a local schema attribute or a global type. + let key = format!("{}.{name}", pkgpath_without_prefix!(pkgpath)); + let is_in_lambda = self.is_in_lambda(); + if !is_in_schema + && !is_in_lambda + && index <= GLOBAL_LEVEL + && !self.local_vars.borrow().contains(name) + && self.setter_keys.borrow().contains(&key) + { + let target = self + .target_vars + .borrow_mut() + .last() + .expect(kcl_error::INTERNAL_ERROR_MSG) + .clone(); + self.build_call( + &ApiFunc::kclvm_scope_get.name(), + &[ + // Runtime context ptr + self.current_runtime_ctx_ptr(), + // Scope ptr + self.current_scope_ptr(), + // Package path + self.native_global_string(&pkgpath, "").into(), + // Attribute name + self.native_global_string(name, "").into(), + // Target + self.native_global_string(&target, "").into(), + // Default + self.builder.build_load(*var, name), + ], + ) + } else { + self.builder.build_load(*var, name) + } }; result = Ok(value); break; diff --git a/kclvm/compiler/src/codegen/llvm/module.rs b/kclvm/compiler/src/codegen/llvm/module.rs index a0f100339..6a8146ac0 100644 --- a/kclvm/compiler/src/codegen/llvm/module.rs +++ b/kclvm/compiler/src/codegen/llvm/module.rs @@ -38,7 +38,7 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { }; } // Pre define global variables with setter functions. - // self.predefine_global_setters(module); + self.predefine_global_setters(module); } pub fn predefine_global_types(&self, name: &str) { @@ -59,7 +59,7 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { /// Predefine all global variables. pub fn predefine_global_setters(&self, module: &'ctx ast::Module) { - // New a function block to the global setter constrcution process. + // New a function block to the global setter construction process. let global_setter_block = self.append_block(""); self.br(global_setter_block); self.builder.position_at_end(global_setter_block); diff --git a/kclvm/compiler/src/codegen/llvm/node.rs b/kclvm/compiler/src/codegen/llvm/node.rs index 108379ddc..de2f1d2c9 100644 --- a/kclvm/compiler/src/codegen/llvm/node.rs +++ b/kclvm/compiler/src/codegen/llvm/node.rs @@ -317,7 +317,10 @@ impl<'ctx> TypedResultWalker<'ctx> for LLVMCodeGenContext<'ctx> { PKG_INIT_FUNCTION_SUFFIX ); let tpe = self.context.void_type(); - let fn_type = tpe.fn_type(&[self.context_ptr_type().into()], false); + let fn_type = tpe.fn_type( + &[self.context_ptr_type().into(), self.scope_ptr_type().into()], + false, + ); let function = module.add_function( // Function name &module_name, @@ -367,10 +370,14 @@ impl<'ctx> TypedResultWalker<'ctx> for LLVMCodeGenContext<'ctx> { ); } let tpe = self.context.void_type(); - let fn_type = tpe.fn_type(&[self.context_ptr_type().into()], false); + let fn_type = tpe.fn_type( + &[self.context_ptr_type().into(), self.scope_ptr_type().into()], + false, + ); module.add_function(&name, fn_type, Some(Linkage::External)) }; let ctx = self.current_runtime_ctx_ptr(); + let scope = self.current_scope_ptr(); let pkgpath_value = self.native_global_string_value(&name); let is_imported = self .build_call( @@ -389,7 +396,8 @@ impl<'ctx> TypedResultWalker<'ctx> for LLVMCodeGenContext<'ctx> { self.builder .build_conditional_branch(is_not_imported, then_block, else_block); self.builder.position_at_end(then_block); - self.builder.build_call(function, &[ctx.into()], ""); + self.builder + .build_call(function, &[ctx.into(), scope.into()], ""); self.br(else_block); self.builder.position_at_end(else_block); } diff --git a/kclvm/runtime/src/_kcl_run.rs b/kclvm/runtime/src/_kcl_run.rs index 6c20449e1..a9ab2cbb0 100644 --- a/kclvm/runtime/src/_kcl_run.rs +++ b/kclvm/runtime/src/_kcl_run.rs @@ -103,6 +103,7 @@ pub unsafe extern "C" fn _kcl_run( ) -> kclvm_size_t { // Init runtime context with options let ctx = Box::new(new_ctx_with_opts(opts, &c2str_vec(path_selector))).into_raw(); + let scope = kclvm_scope_new(); let option_keys = std::slice::from_raw_parts(option_keys, option_len as usize); let option_values = std::slice::from_raw_parts(option_values, option_len as usize); for i in 0..(option_len as usize) { @@ -130,9 +131,7 @@ pub unsafe extern "C" fn _kcl_run( } }) })); - // let scope = Box::into_raw(Box::new(LazyEvalScope::default())); - // let result = std::panic::catch_unwind(|| _kcl_run_in_closure(ctx, scope, kclvm_main_ptr)); - let result = std::panic::catch_unwind(|| _kcl_run_in_closure(ctx, kclvm_main_ptr)); + let result = std::panic::catch_unwind(|| _kcl_run_in_closure(ctx, scope, kclvm_main_ptr)); std::panic::set_hook(prev_hook); KCL_RUNTIME_PANIC_RECORD.with(|record| { let record = record.borrow(); @@ -162,20 +161,26 @@ pub unsafe extern "C" fn _kcl_run( copy_str_to(&json_panic_info, err_buffer, err_buffer_len); // Delete the context kclvm_context_delete(ctx); + // Delete the scope + kclvm_scope_delete(scope); result.is_err() as kclvm_size_t } unsafe fn _kcl_run_in_closure( ctx: *mut Context, + scope: *mut LazyEvalScope, kclvm_main_ptr: u64, // main.k => kclvm_main ) { let kclvm_main = (&kclvm_main_ptr as *const u64) as *const () - as *const extern "C" fn(ctx: *mut kclvm_context_t) -> *mut kclvm_value_ref_t; + as *const extern "C" fn( + ctx: *mut kclvm_context_t, + scope: *mut kclvm_eval_scope_t, + ) -> *mut kclvm_value_ref_t; unsafe { if kclvm_main.is_null() { panic!("kcl program main function not found"); } - (*kclvm_main)(ctx); + (*kclvm_main)(ctx, scope); } } diff --git a/kclvm/runtime/src/_kclvm.bc b/kclvm/runtime/src/_kclvm.bc index 066143924cb7034e6d1607824dfe672f43f97b38..387a1a6aa6e86e282208e5dd5f1e18e0c063cb7f 100644 GIT binary patch delta 2152 zcmZXVdq`7p6vywqTiMW3H{YSCY*KSRz@&UOOk+$5U)P)^T4WD5aESDf+Py)>oEh4D zVOnfyZ6j(pL@A|BQq;glIxvF3z!E{CKa5a>?p@B^oqPYeaQNNx`<(Cjo^!Qot=g*K z6S7|j7ukR8$Qkj7@Y!ty+YcetWDH)#pU*^4Pb}Hqrb}&p6-9bNNLaOO`00aAa7>)d zOF+G|Id%L(Z0}NnPC(sii4+;RhdkLx^kJz=F69MyLI}st{I^5Pk7k4ph7}KsQIV7p z@=G4rz+>ekBSev{z2SBMve~NUV<-X8K6%jS1T@)mHkmq~MJDYgA(74sm!q?+L z{#g^(unjLN3d(RIrk@L-8hW+G7=Tjh4M758JZ?Y(FmR<{UJfvHBh6+Jz}Wi6UG|qU z(5MD(*BMzri>J_W2sGWNc8TtC5uJhppGjMtgy*XJ?XWq93>Z;YJT{os4v+Eg z<-lV^arqQVtUt z^WZwzIO{8h>!3HJ*u4(u@97${69!-nZ!5}S4YR`w|NG^xpHg^Nxdn}kv?B@hrR5kNWP&3_Niv(zf zD?)Jw89|FC9#0&CXtqig+2{9dkZkkTeMr{(I|q{CKbqhQ-I((|PLsLycl|3Yp{#aR zCMBl>6FJ91!y-WoYS&s?{6VKge|hoiz)pg=r|sxS@R!4r-ykJzS9GOpjoL3tJx@AsIlF`6u;Lc|KA`i~{e~uZ9Z< z^UESuZq1T)9RaI#>qahge8I8_l5Uy;Ve>ARynxLMwoG;Hsa@t`qW|FMTjPPRoMRD1 q3}3ly^(55-ZIz}hfMhGSnTQGwI%X3_y$(2VrAAfLU|UK|;r#` z#XMa44dEa=j}18~dLrz+cRBY+uvQb`?)R3+)O~42#fc zDJ|riIPe~ek`uHLNjCS0(+mF1jRQJ)yJ`R9V_NWvr09B>a2l8=i%s>;suvhb!l@2MIj@dL1i;gTX)!~EFt|9-jZCl%hTS%D3E^DZg} zkR^|2-Sw!zrrA^P0~b}tR!|`z6ZwlLAX$1T&OrM#VS!fC*PVxC8;%*csIr!tp=R>I z);OSQkRBCB`=qCGBSkS#vdKr+YG8<0%>Jp+;@e{O~=)V$~uOOd(scm69( z!Hjm6CM2c;6JgfikZ{lfk)yTM4|K}w*IXxGO4`EpQ2YJ&%m=Q(6(HXgWaAx80h@5{ zSD)J&pvj{u8M9Ei`~pfcrq`~(LCw`^L-`UcHH--^Y`eXWpaGHQAJolfc}r u64 { "kclvm_schema_value_check" => crate::kclvm_schema_value_check as *const () as u64, "kclvm_schema_value_new" => crate::kclvm_schema_value_new as *const () as u64, "kclvm_scope_add_setter" => crate::kclvm_scope_add_setter as *const () as u64, - "kclvm_scope_free" => crate::kclvm_scope_free as *const () as u64, + "kclvm_scope_delete" => crate::kclvm_scope_delete as *const () as u64, "kclvm_scope_get" => crate::kclvm_scope_get as *const () as u64, "kclvm_scope_new" => crate::kclvm_scope_new as *const () as u64, "kclvm_scope_set" => crate::kclvm_scope_set as *const () as u64, diff --git a/kclvm/runtime/src/_kclvm_api_spec.rs b/kclvm/runtime/src/_kclvm_api_spec.rs index 2ef978406..b758a6c57 100644 --- a/kclvm/runtime/src/_kclvm_api_spec.rs +++ b/kclvm/runtime/src/_kclvm_api_spec.rs @@ -38,9 +38,9 @@ // api-spec(c): kclvm_eval_scope_t* kclvm_scope_new(); // api-spec(llvm): declare %kclvm_eval_scope_t* @kclvm_scope_new(); -// api-spec: kclvm_scope_free -// api-spec(c): void kclvm_scope_free(kclvm_eval_scope_t* scope); -// api-spec(llvm): declare void @kclvm_scope_free(%kclvm_eval_scope_t* %scope); +// api-spec: kclvm_scope_delete +// api-spec(c): void kclvm_scope_delete(kclvm_eval_scope_t* scope); +// api-spec(llvm): declare void @kclvm_scope_delete(%kclvm_eval_scope_t* %scope); // api-spec: kclvm_scope_add_setter // api-spec(c): void kclvm_scope_add_setter(kclvm_context_t* _ctx, kclvm_eval_scope_t* scope, char* pkg, char* name, uint64_t* setter); diff --git a/kclvm/runtime/src/_kclvm_main_win.c b/kclvm/runtime/src/_kclvm_main_win.c deleted file mode 100644 index 4e6473fdb..000000000 --- a/kclvm/runtime/src/_kclvm_main_win.c +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright The KCL Authors. All rights reserved. - -extern void* kclvm_main(void* ctx); - -extern void kclvm_debug_hello(); -extern void kclvm_debug_print(const char* s); - -__declspec(dllexport) void* kclvm_main_win(void* ctx) { - return kclvm_main(ctx); -} - -__declspec(dllexport) void kclvm_debug_hello_win() { - kclvm_debug_hello(); -} - -__declspec(dllexport) void kclvm_debug_print_win(const char* s) { - kclvm_debug_print(s); -} diff --git a/kclvm/runtime/src/context/api.rs b/kclvm/runtime/src/context/api.rs index 2b3253c4c..aaeb77687 100644 --- a/kclvm/runtime/src/context/api.rs +++ b/kclvm/runtime/src/context/api.rs @@ -148,7 +148,7 @@ pub unsafe extern "C" fn kclvm_scope_new() -> *mut kclvm_eval_scope_t { #[no_mangle] #[runtime_fn] -pub unsafe extern "C" fn kclvm_scope_free(scope: *mut kclvm_eval_scope_t) { +pub unsafe extern "C" fn kclvm_scope_delete(scope: *mut kclvm_eval_scope_t) { drop(Box::from_raw(scope)); } diff --git a/kclvm/tools/src/testing/suite.rs b/kclvm/tools/src/testing/suite.rs index 87f743b6c..68495e729 100644 --- a/kclvm/tools/src/testing/suite.rs +++ b/kclvm/tools/src/testing/suite.rs @@ -8,9 +8,11 @@ use kclvm_driver::{get_kcl_files, get_pkg_list}; use kclvm_parser::{parse_file_force_errors, ParseSessionRef}; #[cfg(feature = "llvm")] use kclvm_runner::build_program; +#[cfg(not(feature = "llvm"))] +use kclvm_runner::exec_program; #[cfg(feature = "llvm")] use kclvm_runner::runner::ProgramRunner; -use kclvm_runner::{exec_program, ExecProgramArgs}; +use kclvm_runner::ExecProgramArgs; use std::time::Instant; /// File suffix for test files. diff --git a/test/grammar/schema/irrelevant_order/simple_10/main.k b/test/grammar/schema/irrelevant_order/simple_10/main.k new file mode 100644 index 000000000..0e59f687f --- /dev/null +++ b/test/grammar/schema/irrelevant_order/simple_10/main.k @@ -0,0 +1,15 @@ +schema Data: + name: str + version?: str + +data1 = Data { + name = data2.name +} + +data2 = Data { + name = "1" + version = version +} + +# Global version +version = "v0.1.0" diff --git a/test/grammar/schema/irrelevant_order/simple_10/stdout.golden b/test/grammar/schema/irrelevant_order/simple_10/stdout.golden new file mode 100644 index 000000000..70d941e06 --- /dev/null +++ b/test/grammar/schema/irrelevant_order/simple_10/stdout.golden @@ -0,0 +1,6 @@ +data1: + name: '1' +data2: + name: '1' + version: v0.1.0 +version: v0.1.0 diff --git a/test/grammar/schema/irrelevant_order/simple_7/main.k b/test/grammar/schema/irrelevant_order/simple_7/main.k new file mode 100644 index 000000000..c090b2995 --- /dev/null +++ b/test/grammar/schema/irrelevant_order/simple_7/main.k @@ -0,0 +1,2 @@ +b = a +a = 1 diff --git a/test/grammar/schema/irrelevant_order/simple_7/stdout.golden b/test/grammar/schema/irrelevant_order/simple_7/stdout.golden new file mode 100644 index 000000000..1bcc2448b --- /dev/null +++ b/test/grammar/schema/irrelevant_order/simple_7/stdout.golden @@ -0,0 +1,2 @@ +b: 1 +a: 1 diff --git a/test/grammar/schema/irrelevant_order/simple_8/main.k b/test/grammar/schema/irrelevant_order/simple_8/main.k new file mode 100644 index 000000000..e7dc4200f --- /dev/null +++ b/test/grammar/schema/irrelevant_order/simple_8/main.k @@ -0,0 +1,3 @@ +b = a + c +a = 1 +c = a + 1 diff --git a/test/grammar/schema/irrelevant_order/simple_8/stdout.golden b/test/grammar/schema/irrelevant_order/simple_8/stdout.golden new file mode 100644 index 000000000..2befd0fca --- /dev/null +++ b/test/grammar/schema/irrelevant_order/simple_8/stdout.golden @@ -0,0 +1,3 @@ +b: 3 +a: 1 +c: 2 diff --git a/test/grammar/schema/irrelevant_order/simple_9/kcl.mod b/test/grammar/schema/irrelevant_order/simple_9/kcl.mod new file mode 100644 index 000000000..e69de29bb diff --git a/test/grammar/schema/irrelevant_order/simple_9/main.k b/test/grammar/schema/irrelevant_order/simple_9/main.k new file mode 100644 index 000000000..af2d1b5a0 --- /dev/null +++ b/test/grammar/schema/irrelevant_order/simple_9/main.k @@ -0,0 +1,3 @@ +import pkg + +output = pkg.output diff --git a/test/grammar/schema/irrelevant_order/simple_9/pkg/base.k b/test/grammar/schema/irrelevant_order/simple_9/pkg/base.k new file mode 100644 index 000000000..17f5d750f --- /dev/null +++ b/test/grammar/schema/irrelevant_order/simple_9/pkg/base.k @@ -0,0 +1,4 @@ +schema MyApp: + name: str + versions: {str:str} + version = versions[name] diff --git a/test/grammar/schema/irrelevant_order/simple_9/pkg/input.k b/test/grammar/schema/irrelevant_order/simple_9/pkg/input.k new file mode 100644 index 000000000..d5b3ec80d --- /dev/null +++ b/test/grammar/schema/irrelevant_order/simple_9/pkg/input.k @@ -0,0 +1,5 @@ +output = MyApp{ + name = name + versions = my_versions +} +name = "my_app" diff --git a/test/grammar/schema/irrelevant_order/simple_9/pkg/versions.k b/test/grammar/schema/irrelevant_order/simple_9/pkg/versions.k new file mode 100644 index 000000000..f65fa4fdf --- /dev/null +++ b/test/grammar/schema/irrelevant_order/simple_9/pkg/versions.k @@ -0,0 +1,3 @@ +my_versions = { + "my-app": "1.0.0" +} \ No newline at end of file diff --git a/test/grammar/schema/irrelevant_order/simple_9/stdout.golden b/test/grammar/schema/irrelevant_order/simple_9/stdout.golden new file mode 100644 index 000000000..56277907c --- /dev/null +++ b/test/grammar/schema/irrelevant_order/simple_9/stdout.golden @@ -0,0 +1,4 @@ +output: + name: my_app + versions: + my-app: 1.0.0