diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f412f89a978..a1304211820 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ concurrency: jobs: build: name: "Build" - timeout-minutes: 25 + timeout-minutes: 30 runs-on: ubuntu-latest env: # Testing runs out of memory without this diff --git a/.insta.yaml b/.insta.yaml new file mode 100644 index 00000000000..000183a3bb2 --- /dev/null +++ b/.insta.yaml @@ -0,0 +1,2 @@ +behavior: + update: "always" diff --git a/Cargo.lock b/Cargo.lock index 76871000730..385d34def63 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,6 +158,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "console" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "windows-sys", +] + [[package]] name = "const_format" version = "0.2.30" @@ -290,6 +302,12 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "flate2" version = "1.0.25" @@ -431,6 +449,20 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" +[[package]] +name = "insta" +version = "1.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a28d25139df397cbca21408bb742cf6837e04cdbebf1b07b760caf971d6a972" +dependencies = [ + "console", + "lazy_static", + "linked-hash-map", + "serde", + "similar", + "yaml-rust", +] + [[package]] name = "itertools" version = "0.10.5" @@ -486,6 +518,12 @@ dependencies = [ "cc", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "log" version = "0.4.17" @@ -787,6 +825,12 @@ dependencies = [ "syn 2.0.15", ] +[[package]] +name = "similar" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" + [[package]] name = "siphasher" version = "0.3.10" @@ -1071,6 +1115,16 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" +[[package]] +name = "uuid" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dad5567ad0cf5b760e5665964bec1b47dfd077ba8a2544b513f3556d3d239a2" +dependencies = [ + "getrandom", + "rand", +] + [[package]] name = "vec_map" version = "0.8.2" @@ -1231,57 +1285,114 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.0" @@ -1302,6 +1413,7 @@ dependencies = [ "indexmap", "indoc", "inflections", + "insta", "itertools", "lazy_static", "lsp-types", @@ -1311,6 +1423,7 @@ dependencies = [ "tree-sitter", "tree-sitter-traversal", "tree-sitter-wing", + "uuid", "wingii", ] @@ -1323,3 +1436,12 @@ dependencies = [ "serde", "serde_json", ] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] diff --git a/docs/06-contributors/020-development.md b/docs/06-contributors/020-development.md index 98b8476ef58..d839f41cd19 100644 --- a/docs/06-contributors/020-development.md +++ b/docs/06-contributors/020-development.md @@ -169,8 +169,9 @@ Note: In CI, tests likely run much slower than on your local machine, so you may ## How do I work only on the compiler? -The following command runs the cargo tests, currently just ensures the valid examples compile and the -invalid ones do not. +The following command runs the rust tests in wingc, including verification that valid tests compile, invalid tests do not compile, and none of them panic. + +It will also make sure to update any snapshots. ```sh npx nx test wingc @@ -190,8 +191,11 @@ To check that your code passes all the lints, run: npx nx lint wingc ``` -If you are using VS Code, you can show clippy errors in your IDE by installing the rust-analyzer extension and setting the option "Rust-analyzer › Check: Command" to "clippy" instead of "check". +### Optional VSCode extensions for working on the compiler + +You can show clippy errors in your IDE by installing the [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) extension and setting the option "Rust-analyzer › Check: Command" to "clippy" instead of "check". +The [insta](https://marketplace.visualstudio.com/items?itemName=mitsuhiko.insta) extension allows you to view snapshots in the tests files. ## How do I make changes to the Wing grammar? diff --git a/libs/wingc/Cargo.toml b/libs/wingc/Cargo.toml index 7f57d215351..3beaff8a273 100644 --- a/libs/wingc/Cargo.toml +++ b/libs/wingc/Cargo.toml @@ -27,3 +27,7 @@ duplicate = "1.0.0" [lib] crate-type = ["rlib", "cdylib"] + +[dev-dependencies] +insta = { version = "1.29.0", features = ["yaml"] } +uuid = { version = "1.3.2", features = ["fast-rng", "v4"] } diff --git a/libs/wingc/project.json b/libs/wingc/project.json index 3b0d74e5704..8e5562162ce 100644 --- a/libs/wingc/project.json +++ b/libs/wingc/project.json @@ -4,11 +4,16 @@ "implicitDependencies": ["sdk", "wingii", "tree-sitter-wing"], "targets": { "test": { - "dependsOn": ["lint"], + "dependsOn": ["^build", "lint"], "executor": "nx:run-commands", "options": { "command": "cargo test", "cwd": "libs/wingc" + }, + "configurations": { + "release": { + "command": "INSTA_UPDATE=\"no\" cargo test" + } } }, "lint": { diff --git a/libs/wingc/src/lsp/completions.rs b/libs/wingc/src/lsp/completions.rs index 6004c0a459d..7f80248c156 100644 --- a/libs/wingc/src/lsp/completions.rs +++ b/libs/wingc/src/lsp/completions.rs @@ -186,9 +186,7 @@ pub fn on_completion(params: lsp_types::CompletionParams) -> CompletionResponse let found_scope = scope_visitor.found_scope.unwrap_or(root_scope); let found_env = found_scope.env.borrow(); let found_env = found_env.as_ref().expect("Scope should have an env"); - let found_stmt_index = scope_visitor - .found_stmt_index - .expect("Found scope should have a statement index"); + let found_stmt_index = scope_visitor.found_stmt_index.unwrap_or_default(); let mut completions = vec![]; @@ -488,3 +486,99 @@ impl<'a> Visit<'a> for ScopeVisitor<'a> { visit_type_annotation(self, node); } } + +#[cfg(test)] +mod tests { + use crate::lsp::completions::*; + use crate::lsp::sync::test_utils::*; + use lsp_types::*; + + /// Creates a snapshot test for a given wing program's completions at a given position + /// In the wing program, place a comment "//^" into the text where the "^" is pointing to the desired character position + /// + /// First parameter will be the name of the tests, as well as the identifier to use for the list of completion in the asserts (see last parameter) + /// Second parameter is the wing code block as a string literal + /// After the first two parameters, any additional are optional statements that should be used for asserting on the given completions. + /// + /// Result is a list of [CompletionItem]s + macro_rules! test_completion_list { + ($name:ident, $code:literal, $($assertion:stmt)*) => { + #[test] + fn $name() { + let text_document_position = load_file_with_contents($code); + let completion = on_completion(CompletionParams { + context: None, + text_document_position, + work_done_progress_params: Default::default(), + partial_result_params: Default::default(), + }); + + if let CompletionResponse::Array($name) = completion { + insta::with_settings!( + { + prepend_module_to_snapshot => false, + omit_expression => true, + snapshot_path => "./snapshots/completions", + }, { + insta::assert_yaml_snapshot!($name); + } + ); + $($assertion)* + } else { + panic!("Expected array of completions"); + } + } + }; + } + + test_completion_list!(empty, "", assert!(empty.len() > 0)); + + test_completion_list!( + new_expression_nested, + r#" +bring cloud; + +new cloud. + //^"#, + assert!(new_expression_nested.len() > 0) + + // all items are classes + assert!(new_expression_nested.iter().all(|item| item.kind == Some(CompletionItemKind::CLASS))) + + // all items are preflight + // TODO https://github.com/winglang/wing/issues/2512 + // assert!(new_expression_nested.iter().all(|item| item.detail.as_ref().unwrap().starts_with("preflight"))) + ); + + test_completion_list!( + static_method_call, + r#" +class Resource { + static hello() {} +} + +Resource. + //^"#, + assert!(static_method_call.len() > 0) + + assert!(static_method_call.iter().filter(|c| c.label == "hello").count() == 1) + ); + + test_completion_list!( + only_show_symbols_in_scope, + r#" +let a = 1; + +if a == 1 { + let x = ""; +} + +let b = + //^ + +let c = 3;"#, + assert!(only_show_symbols_in_scope.len() > 0) + + assert!(only_show_symbols_in_scope.iter().all(|c| c.label != "c")) + ); +} diff --git a/libs/wingc/src/lsp/hover.rs b/libs/wingc/src/lsp/hover.rs index 4ed68d13a38..90e26520036 100644 --- a/libs/wingc/src/lsp/hover.rs +++ b/libs/wingc/src/lsp/hover.rs @@ -308,3 +308,83 @@ fn build_nested_identifier_hover(property: &Symbol, expr: &Expr) -> Option { + #[test] + fn $name() { + let text_document_position_params = load_file_with_contents($code); + let hover = on_hover(HoverParams { + text_document_position_params, + work_done_progress_params: Default::default(), + }); + + if let Some($name) = hover { + insta::with_settings!( + { + prepend_module_to_snapshot => false, + omit_expression => true, + snapshot_path => "./snapshots/hovers", + }, { + insta::assert_yaml_snapshot!($name); + } + ); + $($assertion)* + } else { + panic!("Expected hover data"); + } + } + }; + } + + test_hover_list!( + new_expression_nested, + r#" +bring cloud; + +new cloud. + //^"#, + ); + + test_hover_list!( + class_symbol, + r#" +bring cloud; + +let bucket = new cloud.Bucket(); + //^"#, + ); + + test_hover_list!( + class_symbol_in_closure, + r#" +bring cloud; + +let bucket = new cloud.Bucket(); + //^"#, + ); + + test_hover_list!( + class_property, + r#" +bring cloud; + +let bucket = new cloud.Bucket(); +bucket.addObject + //^"#, + ); +} diff --git a/libs/wingc/src/lsp/notifications.rs b/libs/wingc/src/lsp/notifications.rs index ece3f616923..303da012470 100644 --- a/libs/wingc/src/lsp/notifications.rs +++ b/libs/wingc/src/lsp/notifications.rs @@ -34,10 +34,7 @@ pub unsafe fn send_notification( )) .unwrap(); let data = std::str::from_utf8(std::slice::from_raw_parts(data, data_length as usize)).unwrap(); - panic!( - "send_notification called on non-wasm32 target: {} {}", - notification_type, data - ); + dbg!(format!("send_notification: {} {}", notification_type, data)); } pub fn send_diagnostics(uri: &Url, diagnostics: &Diagnostics) { diff --git a/libs/wingc/src/lsp/snapshots/completions/empty.snap b/libs/wingc/src/lsp/snapshots/completions/empty.snap new file mode 100644 index 00000000000..495103847ec --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/empty.snap @@ -0,0 +1,27 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: assert + kind: 3 + detail: "(bool): void" + insertText: assert($0) + insertTextFormat: 2 +- label: log + kind: 3 + detail: "(str): void" + insertText: log($0) + insertTextFormat: 2 +- label: panic + kind: 3 + detail: "(str): void" + insertText: panic($0) + insertTextFormat: 2 +- label: std + kind: 9 + detail: bring std +- label: throw + kind: 3 + detail: "(str): void" + insertText: throw($0) + insertTextFormat: 2 + diff --git a/libs/wingc/src/lsp/snapshots/completions/new_expression_nested.snap b/libs/wingc/src/lsp/snapshots/completions/new_expression_nested.snap new file mode 100644 index 00000000000..303922eb581 --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/new_expression_nested.snap @@ -0,0 +1,43 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: Api + kind: 7 + detail: preflight class +- label: Bucket + kind: 7 + detail: preflight class +- label: Counter + kind: 7 + detail: preflight class +- label: Function + kind: 7 + detail: preflight class +- label: Queue + kind: 7 + detail: preflight class +- label: Schedule + kind: 7 + detail: preflight class +- label: Secret + kind: 7 + detail: preflight class +- label: Service + kind: 7 + detail: preflight class +- label: Table + kind: 7 + detail: preflight class +- label: Test + kind: 7 + detail: preflight class +- label: TestRunner + kind: 7 + detail: preflight class +- label: Topic + kind: 7 + detail: preflight class +- label: Website + kind: 7 + detail: preflight class + diff --git a/libs/wingc/src/lsp/snapshots/completions/only_show_symbols_in_scope.snap b/libs/wingc/src/lsp/snapshots/completions/only_show_symbols_in_scope.snap new file mode 100644 index 00000000000..3c5d45a6b91 --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/only_show_symbols_in_scope.snap @@ -0,0 +1,37 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: a + kind: 6 + detail: num + insertText: a + insertTextFormat: 2 +- label: assert + kind: 3 + detail: "(bool): void" + insertText: assert($0) + insertTextFormat: 2 +- label: b + kind: 6 + detail: any + insertText: b + insertTextFormat: 2 +- label: log + kind: 3 + detail: "(str): void" + insertText: log($0) + insertTextFormat: 2 +- label: panic + kind: 3 + detail: "(str): void" + insertText: panic($0) + insertTextFormat: 2 +- label: std + kind: 9 + detail: bring std +- label: throw + kind: 3 + detail: "(str): void" + insertText: throw($0) + insertTextFormat: 2 + diff --git a/libs/wingc/src/lsp/snapshots/completions/static_method_call.snap b/libs/wingc/src/lsp/snapshots/completions/static_method_call.snap new file mode 100644 index 00000000000..ff9d61c0e75 --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/static_method_call.snap @@ -0,0 +1,19 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: hello + kind: 2 + detail: "preflight (): void" + insertText: hello($0) + insertTextFormat: 2 +- label: addConnection + kind: 2 + detail: "preflight (AddConnectionProps): void" + insertText: addConnection($0) + insertTextFormat: 2 +- label: isConstruct + kind: 2 + detail: "preflight (any): bool" + insertText: isConstruct($0) + insertTextFormat: 2 + diff --git a/libs/wingc/src/lsp/snapshots/hovers/class_property.snap b/libs/wingc/src/lsp/snapshots/hovers/class_property.snap new file mode 100644 index 00000000000..a4a168adb3c --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/hovers/class_property.snap @@ -0,0 +1,14 @@ +--- +source: libs/wingc/src/lsp/hover.rs +--- +contents: + kind: markdown + value: "```wing\naddObject: preflight (str, str): void\n```" +range: + start: + line: 4 + character: 0 + end: + line: 4 + character: 16 + diff --git a/libs/wingc/src/lsp/snapshots/hovers/class_symbol.snap b/libs/wingc/src/lsp/snapshots/hovers/class_symbol.snap new file mode 100644 index 00000000000..2a23fc9d04b --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/hovers/class_symbol.snap @@ -0,0 +1,14 @@ +--- +source: libs/wingc/src/lsp/hover.rs +--- +contents: + kind: markdown + value: "```wing\npreflight bucket: Bucket\n```" +range: + start: + line: 3 + character: 4 + end: + line: 3 + character: 10 + diff --git a/libs/wingc/src/lsp/snapshots/hovers/class_symbol_in_closure.snap b/libs/wingc/src/lsp/snapshots/hovers/class_symbol_in_closure.snap new file mode 100644 index 00000000000..2a23fc9d04b --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/hovers/class_symbol_in_closure.snap @@ -0,0 +1,14 @@ +--- +source: libs/wingc/src/lsp/hover.rs +--- +contents: + kind: markdown + value: "```wing\npreflight bucket: Bucket\n```" +range: + start: + line: 3 + character: 4 + end: + line: 3 + character: 10 + diff --git a/libs/wingc/src/lsp/snapshots/hovers/new_expression_nested.snap b/libs/wingc/src/lsp/snapshots/hovers/new_expression_nested.snap new file mode 100644 index 00000000000..e9b8444762d --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/hovers/new_expression_nested.snap @@ -0,0 +1,14 @@ +--- +source: libs/wingc/src/lsp/hover.rs +--- +contents: + kind: markdown + value: "```wing\nbring cloud\n```" +range: + start: + line: 3 + character: 4 + end: + line: 3 + character: 9 + diff --git a/libs/wingc/src/lsp/sync.rs b/libs/wingc/src/lsp/sync.rs index f4b90161aab..bcb827e720a 100644 --- a/libs/wingc/src/lsp/sync.rs +++ b/libs/wingc/src/lsp/sync.rs @@ -117,3 +117,72 @@ fn partial_compile(source_file: &str, text: &[u8], jsii_types: &mut TypeSystem) types, }; } + +#[cfg(test)] +pub mod test_utils { + use std::str::FromStr; + use uuid::Uuid; + + use lsp_types::*; + + use super::on_document_did_open; + + static LANGUAGE_ID: &str = "wing"; + + /// Loads a file into the language server + /// + /// Returns a `TextDocumentPositionParams` with the generated URI and a cursor position of an indicated position in the file (using `//^`) + /// + /// Example that gives you the position of the "o" in "Resource.": + /// ``` + /// load_file_with_contents( + /// r#" + /// class Resource { + /// static hello() {} + /// } + /// + /// Resource. + /// //^"# + /// ) + /// ``` + /// + pub fn load_file_with_contents(content: &str) -> TextDocumentPositionParams { + let filename = format!("file:///{}.w", Uuid::new_v4()); + let uri = Url::from_str(&filename).unwrap(); + on_document_did_open(DidOpenTextDocumentParams { + text_document: lsp_types::TextDocumentItem { + uri: uri.clone(), + language_id: LANGUAGE_ID.to_string(), + version: 0, + text: content.to_string(), + }, + }); + + // find the character cursor position by looking for the character above the ^ + let mut char_pos = 0_i32; + let mut line_pos = 0_i32; + // Note: `.chars()` may not 1-to-1 map with characters as expected if using things like emojis + // This generally acceptable for testing, but should not be assumed to be the case in the real language server + // TODO: Add support for grapheme clusters + for char in content.chars() { + if char == '^' { + break; + } else if char == '\n' { + char_pos = 0; + line_pos += 1; + } else { + char_pos += 1; + } + } + + let cursor_position = Position { + line: (line_pos - 1).max(0) as u32, + character: char_pos as u32, + }; + + return TextDocumentPositionParams { + text_document: TextDocumentIdentifier { uri }, + position: cursor_position, + }; + } +} diff --git a/libs/wingc/src/type_check.rs b/libs/wingc/src/type_check.rs index daa0c976df2..10fd7a31a44 100644 --- a/libs/wingc/src/type_check.rs +++ b/libs/wingc/src/type_check.rs @@ -2865,10 +2865,11 @@ impl<'a> TypeChecker<'a> { } else { let mut importer = JsiiImporter::new(&jsii, self.types, self.jsii_types); - // if we're importing the `std` module from the wing sdk, eagerly import all the types within it - // because they aren't typically resolved through the same process as other types - if jsii.assembly_name == WINGSDK_ASSEMBLY_NAME && jsii.alias.name == WINGSDK_STD_MODULE { - importer.deep_import_submodule_to_env(WINGSDK_STD_MODULE); + // if we're importing from the the wing sdk, eagerly import all the types within it + // because they're critical to a typical dx when using wing + // TODO: Improve lazy loading for types in the LSP https://github.com/winglang/wing/issues/2639 + if jsii.assembly_name == WINGSDK_ASSEMBLY_NAME { + importer.deep_import_submodule_to_env(&jsii.alias.name); } importer.import_submodules_to_env(env);