diff --git a/apps/wing/src/commands/compile.ts b/apps/wing/src/commands/compile.ts index 988da37e697..03ae4887371 100644 --- a/apps/wing/src/commands/compile.ts +++ b/apps/wing/src/commands/compile.ts @@ -101,7 +101,7 @@ export async function compile(entrypoint?: string, options?: CompileOptions): Pr const result = []; for (const diagnostic of diagnostics) { - const { message, span, annotations, hints } = diagnostic; + const { message, span, annotations, hints, severity } = diagnostic; const files: File[] = []; const labels: Label[] = []; @@ -145,7 +145,7 @@ export async function compile(entrypoint?: string, options?: CompileOptions): Pr files, { message, - severity: "error", + severity, labels, notes: hints.map((hint) => `hint: ${hint}`), }, @@ -156,7 +156,7 @@ export async function compile(entrypoint?: string, options?: CompileOptions): Pr ); result.push(diagnosticText); } - throw new Error(result.join("\n")); + throw new Error(result.join("\n").trimEnd()); } else if (error instanceof wingCompiler.PreflightError) { let output = await prettyPrintError(error.causedBy, { chalk, diff --git a/examples/tests/invalid/panic.test.w b/examples/tests/invalid/panic.test.w deleted file mode 100644 index a865cf50c97..00000000000 --- a/examples/tests/invalid/panic.test.w +++ /dev/null @@ -1,8 +0,0 @@ -/*\ -env: - WINGC_DEBUG_PANIC: type-checking -\*/ -"I'm fine"; -😱; -//^ Compiler bug when type-checking -"Are you sure?"; diff --git a/examples/tests/valid/debug_env.test.w b/examples/tests/valid/debug_env.test.w deleted file mode 100644 index b17de071e50..00000000000 --- a/examples/tests/valid/debug_env.test.w +++ /dev/null @@ -1,9 +0,0 @@ -bring cloud; - -class A { - b: cloud.Bucket; - new() { - this.b = new cloud.Bucket(); - πŸ—ΊοΈ; - } -} diff --git a/libs/tree-sitter-wing/grammar.js b/libs/tree-sitter-wing/grammar.js index 4ca7b6ac492..b642e1c5e44 100644 --- a/libs/tree-sitter-wing/grammar.js +++ b/libs/tree-sitter-wing/grammar.js @@ -128,7 +128,6 @@ module.exports = grammar({ $.struct_definition, $.enum_definition, $.try_catch_statement, - $.compiler_dbg_env, $.super_constructor_statement, $.throw_statement, $.lift_statement @@ -377,7 +376,6 @@ module.exports = grammar({ $.parenthesized_expression, $.json_literal, $.struct_literal, - $.compiler_dbg_panic, $.optional_unwrap, $.intrinsic ), @@ -463,9 +461,6 @@ module.exports = grammar({ ) ), - compiler_dbg_panic: ($) => "😱", - compiler_dbg_env: ($) => seq("πŸ—ΊοΈ", optional(";")), - call: ($) => prec.left( PREC.CALL, diff --git a/libs/tree-sitter-wing/src/grammar.json b/libs/tree-sitter-wing/src/grammar.json index eb1af85c374..6993511fde8 100644 --- a/libs/tree-sitter-wing/src/grammar.json +++ b/libs/tree-sitter-wing/src/grammar.json @@ -375,10 +375,6 @@ "type": "SYMBOL", "name": "try_catch_statement" }, - { - "type": "SYMBOL", - "name": "compiler_dbg_env" - }, { "type": "SYMBOL", "name": "super_constructor_statement" @@ -2050,10 +2046,6 @@ "type": "SYMBOL", "name": "struct_literal" }, - { - "type": "SYMBOL", - "name": "compiler_dbg_panic" - }, { "type": "SYMBOL", "name": "optional_unwrap" @@ -2462,31 +2454,6 @@ ] } }, - "compiler_dbg_panic": { - "type": "STRING", - "value": "😱" - }, - "compiler_dbg_env": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "πŸ—ΊοΈ" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": ";" - }, - { - "type": "BLANK" - } - ] - } - ] - }, "call": { "type": "PREC_LEFT", "value": 170, diff --git a/libs/tree-sitter-wing/test/corpus/expressions.txt b/libs/tree-sitter-wing/test/corpus/expressions.txt index df0d0c522b8..c4d11a525b4 100644 --- a/libs/tree-sitter-wing/test/corpus/expressions.txt +++ b/libs/tree-sitter-wing/test/corpus/expressions.txt @@ -500,18 +500,6 @@ nil; (expression_statement (nil_value))) -================================================================================ -Debug panic -================================================================================ - -😱; - --------------------------------------------------------------------------------- - -(source - (expression_statement - (compiler_dbg_panic))) - ================================================================================ Duration ================================================================================ diff --git a/libs/tree-sitter-wing/test/corpus/statements/statements.txt b/libs/tree-sitter-wing/test/corpus/statements/statements.txt index b585c9623ad..10098f6d6a8 100644 --- a/libs/tree-sitter-wing/test/corpus/statements/statements.txt +++ b/libs/tree-sitter-wing/test/corpus/statements/statements.txt @@ -529,17 +529,6 @@ if let var x = y {} (reference_identifier)) block: (block))) -================================================================================ -Debug symbol env -================================================================================ - -πŸ—ΊοΈ; - --------------------------------------------------------------------------------- - -(source - (compiler_dbg_env)) - ================================================================================ Super constructor ================================================================================ diff --git a/libs/wingc/examples/compile.rs b/libs/wingc/examples/compile.rs index d9c96cd6ce7..0525d17e392 100644 --- a/libs/wingc/examples/compile.rs +++ b/libs/wingc/examples/compile.rs @@ -15,9 +15,9 @@ pub fn main() { let source_path = Utf8Path::new(&args[1]).canonicalize_utf8().unwrap(); let target_dir: Utf8PathBuf = env::current_dir().unwrap().join("target").try_into().unwrap(); - let results = compile(source_path.parent().unwrap(), &source_path, None, &target_dir); - if results.is_err() { - let mut diags = get_diagnostics(); + let _ = compile(source_path.parent().unwrap(), &source_path, None, &target_dir); + let mut diags = get_diagnostics(); + if !diags.is_empty() { // Sort error messages by line number (ascending) diags.sort(); eprintln!( diff --git a/libs/wingc/src/ast.rs b/libs/wingc/src/ast.rs index 225dc7be9f0..206c62825cf 100644 --- a/libs/wingc/src/ast.rs +++ b/libs/wingc/src/ast.rs @@ -505,7 +505,6 @@ pub enum StmtKind { catch_block: Option, finally_statements: Option, }, - CompilerDebugEnv, ExplicitLift(ExplicitLift), } @@ -677,7 +676,6 @@ pub enum ExprKind { element: Box, }, FunctionClosure(FunctionDefinition), - CompilerDebugPanic, } #[derive(Debug)] diff --git a/libs/wingc/src/comp_ctx.rs b/libs/wingc/src/comp_ctx.rs index 98079c18b32..45952db0b73 100644 --- a/libs/wingc/src/comp_ctx.rs +++ b/libs/wingc/src/comp_ctx.rs @@ -5,7 +5,7 @@ use std::{ use strum::{Display, EnumString}; -use crate::diagnostic::{report_diagnostic, Diagnostic, WingSpan}; +use crate::diagnostic::{report_diagnostic, Diagnostic, DiagnosticSeverity, WingSpan}; /// The different phases of compilation, used for tracking compilation context /// for diagnostic purposes. Feel free to add new phases as needed. @@ -64,32 +64,6 @@ impl CompilationContext { } } -/// Macro used for explicit panics if the environment variable `WINGC_DEBUG_PANIC` is set. -/// This can be used if we want to conditionally panic in certain situations. -/// This is a macro and not a function so we can get the location of the caller -/// in the panic message. -#[macro_export] -macro_rules! dbg_panic { - () => {{ - || -> () { - // Get environment variable to see if we should panic or not - let Ok(dbg_panic) = std::env::var("WINGC_DEBUG_PANIC") else { - return; - }; - - if dbg_panic == "1" - || dbg_panic == "true" - || (dbg_panic - .parse::<$crate::comp_ctx::CompilationPhase>() - .map(|p| p == $crate::comp_ctx::CompilationContext::get_phase()) - .unwrap_or(false)) - { - panic!("User invoked panic"); - } - }(); - }}; -} - pub fn set_custom_panic_hook() { std::panic::set_hook(Box::new(|pi| { // Print backtrace if RUST_BACKTRACE=1 @@ -109,6 +83,7 @@ pub fn set_custom_panic_hook() { span: Some(CompilationContext::get_span()), annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }) })); } diff --git a/libs/wingc/src/diagnostic.rs b/libs/wingc/src/diagnostic.rs index cbd4a19c076..571ec49f00d 100644 --- a/libs/wingc/src/diagnostic.rs +++ b/libs/wingc/src/diagnostic.rs @@ -281,6 +281,7 @@ pub struct Diagnostic { pub annotations: Vec, pub span: Option, pub hints: Vec, + pub severity: DiagnosticSeverity, } impl Diagnostic { @@ -290,6 +291,7 @@ impl Diagnostic { span: Some(span.span()), annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, } } @@ -316,6 +318,11 @@ impl Diagnostic { new } + pub fn severity(mut self, level: DiagnosticSeverity) -> Self { + self.severity = level; + self + } + pub fn report(self) { report_diagnostic(self); } @@ -336,6 +343,13 @@ impl DiagnosticAnnotation { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)] +#[serde(rename_all = "lowercase")] +pub enum DiagnosticSeverity { + Error, + Warning, +} + impl std::fmt::Display for Diagnostic { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if let Some(span) = &self.span { @@ -374,7 +388,7 @@ impl PartialOrd for Diagnostic { } thread_local! { - pub static DIAGNOSTICS: RefCell = RefCell::new(Diagnostics::new()); + static DIAGNOSTICS: RefCell = RefCell::new(Diagnostics::new()); } /// Report a compilation diagnostic @@ -411,7 +425,7 @@ extern "C" { pub fn found_errors() -> bool { DIAGNOSTICS.with(|diagnostics| { let diagnostics = diagnostics.borrow(); - !diagnostics.is_empty() + diagnostics.iter().any(|d| d.severity == DiagnosticSeverity::Error) }) } diff --git a/libs/wingc/src/dtsify/mod.rs b/libs/wingc/src/dtsify/mod.rs index f367e267c64..dbf8bb274ca 100644 --- a/libs/wingc/src/dtsify/mod.rs +++ b/libs/wingc/src/dtsify/mod.rs @@ -328,7 +328,6 @@ impl<'a> DTSifier<'a> { | StmtKind::Assignment { .. } | StmtKind::Scope(_) | StmtKind::TryCatch { .. } - | StmtKind::CompilerDebugEnv | StmtKind::ExplicitLift(_) => {} } diff --git a/libs/wingc/src/files.rs b/libs/wingc/src/files.rs index aade99d82fa..88b96acf424 100644 --- a/libs/wingc/src/files.rs +++ b/libs/wingc/src/files.rs @@ -8,7 +8,7 @@ use std::{ use camino::{Utf8Path, Utf8PathBuf}; -use crate::diagnostic::Diagnostic; +use crate::diagnostic::{Diagnostic, DiagnosticSeverity}; #[derive(Debug)] pub enum FilesError { @@ -32,6 +32,7 @@ impl From for Diagnostic { span: None, annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, } } } diff --git a/libs/wingc/src/fold.rs b/libs/wingc/src/fold.rs index 5881d7487a3..0c2d97ee3c6 100644 --- a/libs/wingc/src/fold.rs +++ b/libs/wingc/src/fold.rs @@ -1,11 +1,8 @@ -use crate::{ - ast::{ - ArgList, BringSource, CalleeKind, CatchBlock, Class, ClassField, ElifBlock, ElifLetBlock, Elifs, Enum, - ExplicitLift, Expr, ExprKind, FunctionBody, FunctionDefinition, FunctionParameter, FunctionSignature, IfLet, - Interface, InterpolatedString, InterpolatedStringPart, Intrinsic, LiftQualification, Literal, New, Reference, - Scope, Stmt, StmtKind, Struct, StructField, Symbol, TypeAnnotation, TypeAnnotationKind, UserDefinedType, - }, - dbg_panic, +use crate::ast::{ + ArgList, BringSource, CalleeKind, CatchBlock, Class, ClassField, ElifBlock, ElifLetBlock, Elifs, Enum, ExplicitLift, + Expr, ExprKind, FunctionBody, FunctionDefinition, FunctionParameter, FunctionSignature, IfLet, Interface, + InterpolatedString, InterpolatedStringPart, Intrinsic, LiftQualification, Literal, New, Reference, Scope, Stmt, + StmtKind, Struct, StructField, Symbol, TypeAnnotation, TypeAnnotationKind, UserDefinedType, }; /// Similar to the `visit` module in `wingc` except each method takes ownership of an @@ -199,7 +196,6 @@ where }), finally_statements: finally_statements.map(|statements| f.fold_scope(statements)), }, - StmtKind::CompilerDebugEnv => StmtKind::CompilerDebugEnv, StmtKind::SuperConstructor { arg_list } => StmtKind::SuperConstructor { arg_list: f.fold_args(arg_list), }, @@ -391,10 +387,6 @@ where element: Box::new(f.fold_expr(*element)), }, ExprKind::FunctionClosure(def) => ExprKind::FunctionClosure(f.fold_function_definition(def)), - ExprKind::CompilerDebugPanic => { - dbg_panic!(); // Handle the debug panic expression (during folding) - ExprKind::CompilerDebugPanic - } }; Expr { id: node.id, diff --git a/libs/wingc/src/jsify.rs b/libs/wingc/src/jsify.rs index f9d363eb17b..05f37a673a4 100644 --- a/libs/wingc/src/jsify.rs +++ b/libs/wingc/src/jsify.rs @@ -17,8 +17,7 @@ use crate::{ Phase, Reference, Scope, Stmt, StmtKind, Symbol, UnaryOperator, UserDefinedType, }, comp_ctx::{CompilationContext, CompilationPhase}, - dbg_panic, - diagnostic::{report_diagnostic, Diagnostic, WingSpan}, + diagnostic::{report_diagnostic, Diagnostic, DiagnosticSeverity, WingSpan}, dtsify::extern_dtsify::ExternDTSifier, file_graph::FileGraph, files::Files, @@ -498,6 +497,7 @@ impl<'a> JSifier<'a> { span: Some(expression.span.clone()), annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }); return new_code!(expr_span, ""); @@ -739,6 +739,7 @@ impl<'a> JSifier<'a> { annotations: vec![], hints: vec![], span: Some(x.1.span.clone()), + severity: DiagnosticSeverity::Error, }); continue; } @@ -752,6 +753,7 @@ impl<'a> JSifier<'a> { annotations: vec![], hints: vec![], span: Some(item.span.clone()), + severity: DiagnosticSeverity::Error, }); continue; }; @@ -772,6 +774,7 @@ impl<'a> JSifier<'a> { annotations: vec![], hints: vec![], span: Some(alias.span.clone()), + severity: DiagnosticSeverity::Error, }); continue; } @@ -786,6 +789,7 @@ impl<'a> JSifier<'a> { annotations: vec![], hints: vec![], span: Some(obj_expression.span.clone()), + severity: DiagnosticSeverity::Error, }); continue; } @@ -796,6 +800,7 @@ impl<'a> JSifier<'a> { annotations: vec![], hints: vec![], span: Some(obj_expression.span.clone()), + severity: DiagnosticSeverity::Error, }); continue; } @@ -841,6 +846,7 @@ impl<'a> JSifier<'a> { span: Some(arg_list.pos_args[0].span.clone()), annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }); return CodeMaker::default(); @@ -1082,11 +1088,6 @@ impl<'a> JSifier<'a> { new_code!(expr_span, "new Set([", item_list, "])") } ExprKind::FunctionClosure(func_def) => self.jsify_function(None, func_def, true, ctx), - ExprKind::CompilerDebugPanic => { - // Handle the debug panic expression (during jsifying) - dbg_panic!(); - new_code!(expr_span, "") - } } } @@ -1494,7 +1495,6 @@ impl<'a> JSifier<'a> { code.close("}"); } } - StmtKind::CompilerDebugEnv => {} StmtKind::ExplicitLift(explicit_lift_block) => { code.open("{"); code.add_code(self.jsify_scope_body(&explicit_lift_block.statements, ctx)); @@ -1730,6 +1730,7 @@ impl<'a> JSifier<'a> { annotations: vec![], hints: vec![], span: Some(span.clone()), + severity: DiagnosticSeverity::Error, }); return None; } @@ -2360,7 +2361,6 @@ fn get_public_symbols(scope: &Scope) -> Vec { } } StmtKind::TryCatch { .. } => {} - StmtKind::CompilerDebugEnv => {} StmtKind::ExplicitLift(_) => {} } } diff --git a/libs/wingc/src/lib.rs b/libs/wingc/src/lib.rs index d7e1a8f1f5d..48d0feeabd0 100644 --- a/libs/wingc/src/lib.rs +++ b/libs/wingc/src/lib.rs @@ -12,7 +12,7 @@ use camino::{Utf8Path, Utf8PathBuf}; use closure_transform::ClosureTransformer; use comp_ctx::set_custom_panic_hook; use const_format::formatcp; -use diagnostic::{found_errors, report_diagnostic, Diagnostic}; +use diagnostic::{found_errors, report_diagnostic, Diagnostic, DiagnosticSeverity}; use dtsify::extern_dtsify::{is_extern_file, ExternDTSifier}; use file_graph::FileGraph; use files::Files; @@ -156,6 +156,26 @@ pub unsafe extern "C" fn wingc_malloc(size: usize) -> *mut u8 { } } +const LOCKFILES: [&'static str; 4] = ["pnpm-lock.yaml", "yarn.lock", "bun.lock", "bun.lockb"]; + +/// Wing sometimes can't find dependencies if they're installed with pnpm/yarn/bun. +/// Try to anticipate any issues that may arise from using pnpm/yarn/bun with winglibs +/// by emitting a warning if dependencies were installed with any of these package managers. +fn emit_warning_for_unsupported_package_managers(project_dir: &Utf8Path) { + for lockfile in &LOCKFILES { + let lockfile_path = project_dir.join(lockfile); + if lockfile_path.exists() { + report_diagnostic(Diagnostic { + message: "The current project has a pnpm/yarn/bun lockfile. Wing hasn't been tested with package managers besides npm, so it may be unable to resolve dependencies to Wing libraries when using these tools. See https://github.com/winglang/wing/issues/6129 for more details.".to_string(), + span: None, + annotations: vec![], + hints: vec![], + severity: DiagnosticSeverity::Warning, + }); + } + } +} + /// Expose a deallocation function to the WASM host /// /// _This implementation is copied from wasm-bindgen_ @@ -190,6 +210,7 @@ pub unsafe extern "C" fn wingc_compile(ptr: u32, len: u32) -> u64 { span: None, annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }); return WASM_RETURN_ERROR; } @@ -206,6 +227,7 @@ pub unsafe extern "C" fn wingc_compile(ptr: u32, len: u32) -> u64 { span: None, annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }); return WASM_RETURN_ERROR; } @@ -272,6 +294,8 @@ pub fn compile( &mut asts, ); + emit_warning_for_unsupported_package_managers(&project_dir); + // -- DESUGARING PHASE -- // Transform all inflight closures defined in preflight into single-method resources @@ -328,6 +352,7 @@ pub fn compile( span: None, annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }); return Err(()); } diff --git a/libs/wingc/src/lifting.rs b/libs/wingc/src/lifting.rs index d5611e06e7e..ba7a6e47210 100644 --- a/libs/wingc/src/lifting.rs +++ b/libs/wingc/src/lifting.rs @@ -6,7 +6,7 @@ use crate::{ UserDefinedType, }, comp_ctx::{CompilationContext, CompilationPhase}, - diagnostic::{report_diagnostic, Diagnostic}, + diagnostic::{report_diagnostic, Diagnostic, DiagnosticSeverity}, jsify::{JSifier, JSifyContext}, type_check::{ get_udt_definition_phase, @@ -73,6 +73,7 @@ impl<'a> LiftVisitor<'a> { message: format!("Cannot access \"{symbol}\" because it is shadowed by another symbol with the same name"), annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }); } } diff --git a/libs/wingc/src/parser.rs b/libs/wingc/src/parser.rs index 383f3bc9e1c..ccb59f4209d 100644 --- a/libs/wingc/src/parser.rs +++ b/libs/wingc/src/parser.rs @@ -18,13 +18,13 @@ use crate::ast::{ }; use crate::comp_ctx::{CompilationContext, CompilationPhase}; use crate::diagnostic::{ - report_diagnostic, Diagnostic, DiagnosticResult, WingLocation, WingSpan, ERR_EXPECTED_SEMICOLON, + report_diagnostic, Diagnostic, DiagnosticResult, DiagnosticSeverity, WingLocation, WingSpan, ERR_EXPECTED_SEMICOLON, }; use crate::file_graph::FileGraph; use crate::files::Files; use crate::type_check::{CLASS_INFLIGHT_INIT_NAME, CLASS_INIT_NAME}; use crate::{ - dbg_panic, is_absolute_path, TRUSTED_LIBRARY_NPM_NAMESPACE, WINGSDK_BRINGABLE_MODULES, WINGSDK_STD_MODULE, + is_absolute_path, TRUSTED_LIBRARY_NPM_NAMESPACE, WINGSDK_BRINGABLE_MODULES, WINGSDK_STD_MODULE, WINGSDK_TEST_CLASS_NAME, }; @@ -226,6 +226,7 @@ pub fn parse_wing_project( span: None, annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }); // return a list of all files just so we can continue type-checking @@ -653,7 +654,6 @@ impl<'s> Parser<'s> { "try_catch_statement" => self.build_try_catch_statement(statement_node, phase)?, "struct_definition" => self.build_struct_definition_statement(statement_node, phase)?, "test_statement" => self.build_test_statement(statement_node)?, - "compiler_dbg_env" => StmtKind::CompilerDebugEnv, "super_constructor_statement" => self.build_super_constructor_statement(statement_node, phase)?, "lift_statement" => self.build_lift_statement(statement_node, phase)?, "ERROR" => return self.with_error("Expected statement", statement_node), @@ -1568,6 +1568,7 @@ impl<'s> Parser<'s> { span: Some(self.node_span(&class_element)), annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }); } @@ -2254,11 +2255,6 @@ impl<'s> Parser<'s> { "json_literal" => self.build_json_literal(&expression_node, phase), "struct_literal" => self.build_struct_literal(&expression_node, phase), "optional_unwrap" => self.build_optional_unwrap_expression(&expression_node, phase), - "compiler_dbg_panic" => { - // Handle the debug panic expression (during parsing) - dbg_panic!(); - Ok(Expr::new(ExprKind::CompilerDebugPanic, expression_span)) - } other => self.report_unimplemented_grammar(other, "expression", expression_node), } } @@ -2759,6 +2755,7 @@ impl<'s> Parser<'s> { }), annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }; report_diagnostic(diag); } else if node.kind() == "AUTOMATIC_BLOCK" { @@ -2777,6 +2774,7 @@ impl<'s> Parser<'s> { }), annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }; report_diagnostic(diag); } else if !self.error_nodes.borrow().contains(&node.id()) { @@ -2797,6 +2795,7 @@ impl<'s> Parser<'s> { span: Some(self.node_span(&target_node)), annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }; report_diagnostic(diag); } @@ -2968,7 +2967,6 @@ fn is_valid_module_statement(stmt: &Stmt) -> bool { StmtKind::Interface(_) => true, StmtKind::Struct { .. } => true, StmtKind::Enum { .. } => true, - StmtKind::CompilerDebugEnv => true, // --- these are all uncool --- StmtKind::SuperConstructor { .. } => false, StmtKind::If { .. } => false, diff --git a/libs/wingc/src/type_check.rs b/libs/wingc/src/type_check.rs index 6ebbb142a02..765b499481f 100644 --- a/libs/wingc/src/type_check.rs +++ b/libs/wingc/src/type_check.rs @@ -17,7 +17,7 @@ use crate::ast::{ UserDefinedType, }; use crate::comp_ctx::{CompilationContext, CompilationPhase}; -use crate::diagnostic::{report_diagnostic, Diagnostic, DiagnosticAnnotation, TypeError, WingSpan}; +use crate::diagnostic::{report_diagnostic, Diagnostic, DiagnosticAnnotation, DiagnosticSeverity, TypeError, WingSpan}; use crate::docs::Docs; use crate::file_graph::FileGraph; use crate::type_check::has_type_stmt::HasStatementVisitor; @@ -27,11 +27,10 @@ use crate::visit_context::{VisitContext, VisitorWithContext}; use crate::visit_stmt_before_super::{CheckSuperCtorLocationVisitor, CheckValidBeforeSuperVisitor}; use crate::visit_types::{VisitType, VisitTypeMut}; use crate::{ - dbg_panic, debug, CONSTRUCT_BASE_CLASS, CONSTRUCT_BASE_INTERFACE, CONSTRUCT_NODE_PROPERTY, UTIL_CLASS_NAME, - WINGSDK_ARRAY, WINGSDK_ASSEMBLY_NAME, WINGSDK_BRINGABLE_MODULES, WINGSDK_DURATION, WINGSDK_GENERIC, - WINGSDK_IRESOURCE, WINGSDK_JSON, WINGSDK_MAP, WINGSDK_MUT_ARRAY, WINGSDK_MUT_JSON, WINGSDK_MUT_MAP, WINGSDK_MUT_SET, - WINGSDK_NODE, WINGSDK_RESOURCE, WINGSDK_SET, WINGSDK_SIM_IRESOURCE_FQN, WINGSDK_STD_MODULE, WINGSDK_STRING, - WINGSDK_STRUCT, + debug, CONSTRUCT_BASE_CLASS, CONSTRUCT_BASE_INTERFACE, CONSTRUCT_NODE_PROPERTY, UTIL_CLASS_NAME, WINGSDK_ARRAY, + WINGSDK_ASSEMBLY_NAME, WINGSDK_BRINGABLE_MODULES, WINGSDK_DURATION, WINGSDK_GENERIC, WINGSDK_IRESOURCE, WINGSDK_JSON, + WINGSDK_MAP, WINGSDK_MUT_ARRAY, WINGSDK_MUT_JSON, WINGSDK_MUT_MAP, WINGSDK_MUT_SET, WINGSDK_NODE, WINGSDK_RESOURCE, + WINGSDK_SET, WINGSDK_SIM_IRESOURCE_FQN, WINGSDK_STD_MODULE, WINGSDK_STRING, WINGSDK_STRUCT, }; use camino::{Utf8Path, Utf8PathBuf}; use derivative::Derivative; @@ -1563,6 +1562,7 @@ impl Types { span: Some(span.clone()), annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }); existing_type_option.replace(error); return; @@ -1902,6 +1902,7 @@ impl<'a> TypeChecker<'a> { span: Some(spanned.span()), annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }); (self.make_error_variable_info(), Phase::Independent) @@ -1913,6 +1914,7 @@ impl<'a> TypeChecker<'a> { span: Some(spanned.span()), annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }); } @@ -1922,6 +1924,7 @@ impl<'a> TypeChecker<'a> { span: Some(spanned.span()), annotations: vec![], hints: hints.iter().map(|h| h.to_string()).collect(), + severity: DiagnosticSeverity::Error, }); } @@ -1936,6 +1939,7 @@ impl<'a> TypeChecker<'a> { span: Some(spanned.span()), annotations, hints: vec![], + severity: DiagnosticSeverity::Error, }); } @@ -1945,6 +1949,7 @@ impl<'a> TypeChecker<'a> { span: None, annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }); } @@ -1960,6 +1965,7 @@ impl<'a> TypeChecker<'a> { span: Some(span), annotations, hints, + severity: DiagnosticSeverity::Error, }); self.types.error() @@ -2241,19 +2247,6 @@ new cloud.Function(@inflight("./handler.ts"), lifts: { bucket: ["put"] }); ExprKind::JsonLiteral { is_mut, element } => self.type_check_json_lit(is_mut, element, env, exp), ExprKind::JsonMapLiteral { fields } => self.type_check_json_map_lit(fields, env, exp), ExprKind::FunctionClosure(func_def) => self.type_check_closure(func_def, env), - ExprKind::CompilerDebugPanic => { - // Handle the debug panic expression (during type-checking) - dbg_panic!(); - ( - self.type_error(TypeError { - message: "Panic expression".to_string(), - span: exp.span.clone(), - annotations: vec![], - hints: vec![], - }), - env.phase, - ) - } }; // If we're inflight but the expression is a lifted (preflight) expression then make it immutable @@ -3638,6 +3631,7 @@ new cloud.Function(@inflight("./handler.ts"), lifts: { bucket: ["put"] }); span: None, annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }), ); return; @@ -3661,6 +3655,7 @@ new cloud.Function(@inflight("./handler.ts"), lifts: { bucket: ["put"] }); span: None, annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }), ); return; @@ -4248,10 +4243,6 @@ new cloud.Function(@inflight("./handler.ts"), lifts: { bucket: ["put"] }); } => { tc.type_check_try_catch(try_statements, catch_block, finally_statements, env); } - StmtKind::CompilerDebugEnv => { - eprintln!("[symbol environment at {}]", stmt.span); - eprintln!("{}", env); - } StmtKind::SuperConstructor { arg_list } => { tc.type_check_super_constructor_against_parent_initializer(stmt, arg_list, env); } @@ -5477,6 +5468,7 @@ new cloud.Function(@inflight("./handler.ts"), lifts: { bucket: ["put"] }); span: lookup.name.span.clone(), }], hints: vec![format!("Change type to match first declaration: {}", lookup.type_)], + severity: DiagnosticSeverity::Error, }); } } else { @@ -6550,6 +6542,7 @@ new cloud.Function(@inflight("./handler.ts"), lifts: { bucket: ["put"] }); hints: vec![format!( "the definition of \"{property}\" needs a broader access modifier like \"pub\" or \"protected\" to be used outside of \"{class}\"", )], + severity: DiagnosticSeverity::Error, }); } } @@ -6565,6 +6558,7 @@ new cloud.Function(@inflight("./handler.ts"), lifts: { bucket: ["put"] }); hints: vec![format!( "the definition of \"{property}\" needs a broader access modifier like \"pub\" to be used outside of \"{class}\"", )], + severity: DiagnosticSeverity::Error, }); } } diff --git a/libs/wingc/src/valid_json_visitor.rs b/libs/wingc/src/valid_json_visitor.rs index 8778a478bbf..dbe08bb342e 100644 --- a/libs/wingc/src/valid_json_visitor.rs +++ b/libs/wingc/src/valid_json_visitor.rs @@ -1,6 +1,6 @@ use crate::{ ast::{Expr, ExprKind, Intrinsic, IntrinsicKind, Scope}, - diagnostic::{report_diagnostic, Diagnostic}, + diagnostic::{report_diagnostic, Diagnostic, DiagnosticSeverity}, type_check::{JsonData, JsonDataKind, SpannedTypeInfo, Type, Types}, visit::{self, Visit}, }; @@ -32,6 +32,7 @@ impl<'a> ValidJsonVisitor<'a> { span: Some(inner.span.clone()), annotations: vec![], hints: vec![], + severity: DiagnosticSeverity::Error, }) } } diff --git a/libs/wingc/src/visit.rs b/libs/wingc/src/visit.rs index fcf68c9a755..839fc2c611f 100644 --- a/libs/wingc/src/visit.rs +++ b/libs/wingc/src/visit.rs @@ -1,10 +1,7 @@ -use crate::{ - ast::{ - ArgList, BringSource, CalleeKind, Class, Elifs, Enum, Expr, ExprKind, FunctionBody, FunctionDefinition, - FunctionParameter, FunctionSignature, IfLet, Interface, InterpolatedStringPart, Literal, New, Reference, Scope, - Stmt, StmtKind, Struct, Symbol, TypeAnnotation, TypeAnnotationKind, UserDefinedType, - }, - dbg_panic, +use crate::ast::{ + ArgList, BringSource, CalleeKind, Class, Elifs, Enum, Expr, ExprKind, FunctionBody, FunctionDefinition, + FunctionParameter, FunctionSignature, IfLet, Interface, InterpolatedStringPart, Literal, New, Reference, Scope, Stmt, + StmtKind, Struct, Symbol, TypeAnnotation, TypeAnnotationKind, UserDefinedType, }; /// Visitor pattern inspired by implementation from https://docs.rs/syn/latest/syn/visit/index.html @@ -219,7 +216,6 @@ where v.visit_scope(finally_statements); } } - StmtKind::CompilerDebugEnv => {} StmtKind::ExplicitLift(explict_lift) => { for q in explict_lift.qualifications.iter() { v.visit_expr(&q.obj); @@ -401,10 +397,6 @@ where ExprKind::FunctionClosure(def) => { v.visit_function_definition(def); } - ExprKind::CompilerDebugPanic => { - // Handle the debug panic expression (during visiting) - dbg_panic!(); - } } } diff --git a/libs/wingcompiler/src/compile.ts b/libs/wingcompiler/src/compile.ts index d1eb23002fd..81694c112cb 100644 --- a/libs/wingcompiler/src/compile.ts +++ b/libs/wingcompiler/src/compile.ts @@ -177,6 +177,9 @@ export async function compile(entrypoint: string, options: CompileOptions): Prom color: options.color, log, }); + if (compileForPreflightResult.diagnostics.length > 0) { + throw new CompileError(compileForPreflightResult.diagnostics); + } if (isEntrypointFile(entrypoint)) { let preflightEnv: Record = { @@ -233,6 +236,7 @@ interface CompileForPreflightResult { readonly compilerOutput?: { imported_namespaces: string[]; }; + readonly diagnostics: wingCompiler.WingDiagnostic[]; } async function compileForPreflight(props: { @@ -244,22 +248,35 @@ async function compileForPreflight(props: { log?: (...args: any[]) => void; }): Promise { if (props.entrypointFile.endsWith(".ts")) { - const typescriptFramework = await import("@wingcloud/framework") - .then((m) => m.internal) - .catch((err) => { - throw new Error(`\ -Failed to load "@wingcloud/framework": ${err.message} - -To use Wing with TypeScript files, you must install "@wingcloud/framework" as a dependency of your project. -npm i @wingcloud/framework -`); - }); + const diagnostics: wingCompiler.WingDiagnostic[] = []; + let typescriptFramework; + try { + typescriptFramework = (await import("@wingcloud/framework")).internal; + } catch (err) { + return { + preflightEntrypoint: "", + diagnostics: [ + { + message: `\ + Failed to load "@wingcloud/framework": ${(err as any).message} + + To use Wing with TypeScript files, you must install "@wingcloud/framework" as a dependency of your project. + npm i @wingcloud/framework + `, + severity: "error", + annotations: [], + hints: [], + }, + ], + }; + } return { preflightEntrypoint: await typescriptFramework.compile({ workDir: props.workDir, entrypoint: props.entrypointFile, }), + diagnostics, }; } else { let env: Record = { @@ -279,7 +296,7 @@ npm i @wingcloud/framework }, }); - const errors: wingCompiler.WingDiagnostic[] = []; + const diagnostics: wingCompiler.WingDiagnostic[] = []; function send_diagnostic(data_ptr: number, data_len: number) { const data_buf = Buffer.from( @@ -288,31 +305,25 @@ npm i @wingcloud/framework data_len ); const data_str = new TextDecoder().decode(data_buf); - errors.push(JSON.parse(data_str)); + diagnostics.push(JSON.parse(data_str)); } const arg = `${normalPath(props.entrypointFile)};${normalPath(props.workDir)};${normalPath( props.wingDir )}`; props.log?.(`invoking %s with: "%s"`, WINGC_COMPILE, arg); - let compileSuccess: boolean; let compilerOutput: string | number = ""; try { compilerOutput = wingCompiler.invoke(wingc, WINGC_COMPILE, arg); - compileSuccess = compilerOutput !== 0; } catch (error) { // This is a bug in the compiler, indicate a compilation failure. // The bug details should be part of the diagnostics handling below. - compileSuccess = false; - } - if (!compileSuccess) { - // This is a bug in the user's code. Print the compiler diagnostics. - throw new CompileError(errors); } return { preflightEntrypoint: join(props.workDir, WINGC_PREFLIGHT), compilerOutput: JSON.parse(compilerOutput as string), + diagnostics, }; } } diff --git a/libs/wingcompiler/src/wingc.ts b/libs/wingcompiler/src/wingc.ts index 72badc4ffde..0d270d4ad48 100644 --- a/libs/wingcompiler/src/wingc.ts +++ b/libs/wingcompiler/src/wingc.ts @@ -230,6 +230,7 @@ export interface WingDiagnostic { span: WingSpan; }[]; hints: string[]; + severity: "error" | "warning"; } export interface WingSpan { diff --git a/tools/hangar/__snapshots__/invalid.ts.snap b/tools/hangar/__snapshots__/invalid.ts.snap index 1dee5e09a54..6906277f3e5 100644 --- a/tools/hangar/__snapshots__/invalid.ts.snap +++ b/tools/hangar/__snapshots__/invalid.ts.snap @@ -7,8 +7,6 @@ exports[`access_hidden_namespace.test.w 1`] = ` 7 | new core.NodeJsCode("/test.txt"); // This should fail even though \`fs.TextFile\` extends \`core.FileBase\` because we didn't bring in \`core\` explicitly. | ^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -289,8 +287,6 @@ error: Cannot access private member "private_static_method" of "Foo" | = hint: the definition of "private_static_method" needs a broader access modifier like "pub" or "protected" to be used outside of "Foo" - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -359,8 +355,6 @@ error: Expected identifier "subdir2" to be a variable, but it's a namespace 17 | let e = subdir2.MyPrivateEnum.A; | ^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -402,8 +396,6 @@ error: Member "f" does not exist in "Construct" 8 | this.f = 1; // Can't access static fields through \`this\` | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -454,8 +446,6 @@ error: "cloud" is already defined 4 | bring cloud; | ^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -487,8 +477,6 @@ error: Cannot bring Wing directories that contain sub-directories with invalid c | = hint: Directory names must start with a letter or underscore and contain only letters, numbers, and underscores. - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -509,8 +497,6 @@ error: Unable to load "foobar": Module not found in "/bring_jsii.test. 4 | bring "foobar" as baz; | ^^^^^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -538,8 +524,6 @@ error: Symbol "Foo" has multiple definitions in "/inner" 1 | bring "./subdir" as subdir; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -574,8 +558,6 @@ error: Cannot bring module "./bring_local_dir.test.w" since it is an entrypoint 10 | bring "./bring_local_dir.test.w" as qux; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -610,8 +592,6 @@ error: Preflight field "x" is not initialized 10 | x: num; | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -639,8 +619,6 @@ error: Cannot set scope of non-standard preflight class "S3Backend" using \`in\` 15 | new cdktf.S3Backend(this, cdktf.S3BackendConfig {bucket: "foo", key: "bar"}) in this; | ^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -675,8 +653,6 @@ error: Expected type to be "num", but got "str" instead 20 | return "a"; | ^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -697,8 +673,6 @@ error: Cannot call into inflight phase while preflight 12 | foo.do(); | ^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -726,8 +700,6 @@ error: Cannot access "x" because it is shadowed by another symbol with the same 22 | log(x); | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1066,8 +1038,6 @@ error: Expected type to be "str", but got "num" instead 223 | return 5; | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1097,8 +1067,6 @@ error: Expected type to be "inflight (message: str): void", but got "inflight (x 12 | | }); | \\-^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1123,8 +1091,6 @@ error: Member "node" does not exist in "IConstruct" | = hint: use nodeof(x) to access the tree node on a preflight class - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1313,8 +1279,6 @@ error: Member "copyMut" does not exist in "MutSet" 46 | let ss4 = ss3.copyMut(); | ^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1398,8 +1362,6 @@ error: Expected 1 positional argument(s) but got 0 65 | super(); | ^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1426,8 +1388,6 @@ error: Could not type check "/cyclic_bring3.w" due to cyclic bring sta 1 | bring "./cyclic_bring3.w" as foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1454,8 +1414,6 @@ error: Could not type check "/cyclic_bring1.w" due to cyclic bring sta 1 | bring "./cyclic_bring1.w" as foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1482,8 +1440,6 @@ error: Could not type check "/cyclic_bring2.w" due to cyclic bring sta 1 | bring "./cyclic_bring2.w" as foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1497,8 +1453,6 @@ exports[`diags_with_multibyte_chars.test.w 1`] = ` 4 | asdf; | ^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1519,8 +1473,6 @@ error: Property not found 8 | let two = SomeEnum.TWO.TWO; | ^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1634,8 +1586,6 @@ error: Expected type to be "MutSet", but got "Set" instead 72 | assert(e1 == e2); | ^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1755,8 +1705,6 @@ error: Expression of type "IPreflightInterface" references an unknown preflight = hint: Use a \`lift\` block to explicitly qualify the preflight object and disable this error = hint: For details see: https://www.winglang.io/docs/concepts/inflights#explicit-lift-qualification - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1770,8 +1718,6 @@ exports[`extern.test.w 1`] = ` 2 | extern "./sad.js" static getNum(): num; | ^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1785,8 +1731,6 @@ exports[`extern_static.test.w 1`] = ` 2 | extern "../valid/external_ts.ts" inflight getGreeting(name: str): str; | ^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1821,8 +1765,6 @@ error: Preflight field "x" is not initialized 10 | x: num; | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1843,8 +1785,6 @@ error: Unable to iterate over "Bucket" 5 | for test in bucket { | ^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1942,8 +1882,6 @@ error: Expected type to be "Options", but got "str" instead 31 | invalidCombinationFunc2(1, 2, prefix: "debug", priority: 0, "hello", "world"); | ^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -1978,8 +1916,6 @@ error: Expected type to be "str", but got "Array" instead 4 | func(["a", "b", "c"]); // should fail as the parameter is variadic | ^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2007,8 +1943,6 @@ error: Optional parameters must always be after all non-optional parameters. 9 | let my_func3 = (a: num, b: str?, c: bool) => {}; | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2064,8 +1998,6 @@ error: Expected type to be "Bucket", but got "bool" instead 24 | funcBucket(bucket1, true, bucket2); | ^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2156,8 +2088,6 @@ error: Expected type to be "preflight (construct: IConstruct): Node", but got "s 16 | nodeof = "!"; | ^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2255,8 +2185,6 @@ error: Expected type to be "bool", but got "Array" instead 32 | let s4: Set = Set[[3]]; | ^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2305,8 +2233,6 @@ error: Class "r" does not implement method "method3" of interface "I3" 30 | class r impl I3 { | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2396,8 +2322,6 @@ error: Indexing into an inferred type is not supported 41 | log(x[0]); | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2576,8 +2500,6 @@ error: Unable to infer type by usage, an explicit type annotation is required 4 | let preflightClosureArgs = (nice) => { return true; }; | ^^^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2612,8 +2534,6 @@ error: Cannot create preflight class "PreflightClass" in inflight phase 19 | new PreflightClass(); | ^^^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2629,8 +2549,6 @@ exports[`inflight_class_dup_init.test.w 1`] = ` 8 | | } | \\---^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2644,8 +2562,6 @@ exports[`inflight_class_in_preflight.test.w 1`] = ` 5 | new Foo(); | ^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2659,8 +2575,6 @@ exports[`inflight_class_interface_structural_typing.test.w 1`] = ` 26 | let x: IGoo = new NotGoo(); | ^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2681,8 +2595,6 @@ error: Inflight path must be a non-interpolated string literal 2 | let func: inflight (): str = @inflight(funkPath, lifts: [ | ^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2706,8 +2618,6 @@ error: Variable is not reassignable 8 | ylet = 456; | ^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2744,8 +2654,6 @@ error: Expression of type "Bucket" references an unknown preflight object, can't = hint: Use a \`lift\` block to explicitly qualify the preflight object and disable this error = hint: For details see: https://www.winglang.io/docs/concepts/inflights#explicit-lift-qualification - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2772,8 +2680,6 @@ error: Expression of type "Queue" references an unknown preflight object, can't = hint: Use a \`lift\` block to explicitly qualify the preflight object and disable this error = hint: For details see: https://www.winglang.io/docs/concepts/inflights#explicit-lift-qualification - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2800,8 +2706,6 @@ error: Expression of type "Bucket" references an unknown preflight object, can't = hint: Use a \`lift\` block to explicitly qualify the preflight object and disable this error = hint: For details see: https://www.winglang.io/docs/concepts/inflights#explicit-lift-qualification - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2933,8 +2837,6 @@ error: Expected type to be "preflight (): void", but got "inflight (): void" ins | = hint: expected phase to be preflight, but got inflight instead - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2955,8 +2857,6 @@ error: @dirname cannot be used in inflight 2 | let x = @dirname; | ^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -2968,9 +2868,7 @@ exports[`invalid compile directory 1`] = ` --> ../../../examples/tests/invalid/lib/extern_above.w:2:3 | 2 | extern "../../valid/external_ts.ts" static getGreeting(name: str): str; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" `; exports[`invalid_call_before_super.w 1`] = ` @@ -3057,8 +2955,6 @@ error: super() should be called at the top scope of the constructor 73 | super(5); // Super can't be called from inner scope | ^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3072,8 +2968,6 @@ exports[`issue_2767.test.w 1`] = ` 4 | x.set("hello", new cloud.Bucket()); | ^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3089,8 +2983,6 @@ exports[`jsii_access_modifiers.test.w 1`] = ` | = hint: the definition of "createTopic" needs a broader access modifier like "pub" to be used outside of "Bucket" - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3288,8 +3180,6 @@ error: "Bucket" is not a legal JSON value 137 | Json { bucket }; | ^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3310,8 +3200,6 @@ error: Expected type to be "Json", but got "str?" instead 67 | outerJson(optionalStr()); | ^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3325,8 +3213,6 @@ exports[`json_static.test.w 1`] = ` 4 | immutObj.set("a", "foo"); | ^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3340,8 +3226,6 @@ exports[`map_entries.test.w 1`] = ` 2 | let someStr: str = mapToNumber.entries().at(0).value; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3384,8 +3268,6 @@ error: A function whose return type is "str" must return a value. 42 | | }; | \\-^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3413,8 +3295,6 @@ error: Expected '}' 19 | if (x > 10) { | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3505,8 +3385,6 @@ error: Expected type to be "MutMap", but got "MutMap" instead 24 | let m5: MutMap = m4; | ^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3545,8 +3423,6 @@ error: Expected type to be "num", but got "nil" instead | = hint: to allow "nil" assignment use optional type: "num?" - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3675,32 +3551,12 @@ error: Variable is not reassignable 50 | hi = "bye"; | ^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) Duration " `; -exports[`panic.test.w 1`] = ` -"error: Compiler bug during type-checking ('panicked at libs/wingc/src/type_check.rs:LINE:COL: -User invoked panic'), please report at https://www.winglang.io/contributing/start-here/bugs - --> ../../../examples/tests/invalid/panic.test.w:6:1 - | -6 | 😱; - | ^^ - - - -Tests 1 failed (1) -Snapshots 1 skipped -Test Files 1 failed (1) -Duration " -`; - -exports[`panic.test.w 2`] = `"Panicked, backtrace not captured: Unsupported"`; - exports[`parameters.test.w 1`] = ` "Error: Parameter validation errors: - must have required property 'foo' @@ -3757,8 +3613,6 @@ error: Expected type to be "preflight (inflight (str): str): void", but got "pre 25 | accepts_callback(callback); // error | ^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3772,8 +3626,6 @@ exports[`preflight_from_inflight.test.w 1`] = ` 15 | this.r.myPreflight(); | ^^^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3801,8 +3653,6 @@ error: Expected type to be "str", but got "num" instead 10 | let n: str = arr.at(0); | ^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3816,8 +3666,6 @@ exports[`private_constructor.test.w 1`] = ` 3 | new jsii_fixture.JsiiClassWithPrivateConstructor(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3852,8 +3700,6 @@ error: Enums must be public ("pub") or private 10 | protected enum MyEnum {} | ^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -3908,8 +3754,6 @@ error: Variable is not reassignable 42 | arg = 0; | ^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4026,8 +3870,6 @@ error: Multiple or ambiguous modifiers found | | possible redundant modifier | possible redundant modifier - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4041,8 +3883,6 @@ exports[`resource_access_field_as_method.test.w 1`] = ` 9 | x.name(); | ^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4069,8 +3909,6 @@ error: Expression of type "Bucket" references an unknown preflight object, can't = hint: Use a \`lift\` block to explicitly qualify the preflight object and disable this error = hint: For details see: https://www.winglang.io/docs/concepts/inflights#explicit-lift-qualification - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4084,8 +3922,6 @@ exports[`resource_inflight.test.w 1`] = ` 4 | new cloud.Bucket(); // Should fail because we can't create resources inflight | ^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4120,8 +3956,6 @@ error: Inflight constructors cannot have parameters 9 | inflight new(x: num) {} | ^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4163,8 +3997,6 @@ error: Unexpected return value from void function. Return type annotations are r 19 | return 9; | ^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4199,8 +4031,6 @@ error: Inflight classes cannot have a scope 17 | new InflightClass() in pc; | ^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4491,8 +4321,6 @@ error: Return value cannot have a non-serializable type "MyStructWithNonSerializ 53 | | } | \\---^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4547,8 +4375,6 @@ error: Expression of type "Bucket" references an unknown preflight object, can't = hint: Use a \`lift\` block to explicitly qualify the preflight object and disable this error = hint: For details see: https://www.winglang.io/docs/concepts/inflights#explicit-lift-qualification - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4583,8 +4409,6 @@ error: Expected "b" to be a type but it's a variable 5 | inflight class e extends b {} | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4619,8 +4443,6 @@ error: Expected continue statement to be inside of a loop (while/for) 15 | continue; | ^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4648,8 +4470,6 @@ error: Expected type to be "bool", but got "num" instead 8 | if !n || true {} | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4663,8 +4483,6 @@ exports[`std_containers.test.w 1`] = ` 3 | let c = a.concat(b); | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4698,8 +4516,6 @@ error: Expected type to be "stringable", but got "B" instead | = hint: str, num, bool, json, and enums are stringable - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4760,8 +4576,6 @@ error: Missing required field "contentType" from "BucketPutOptions" 11 | bucket1.put(file: "file.txt", "data"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4808,8 +4622,6 @@ error: Struct "C" contains field "b" which cannot be represented in Json 22 | C.fromJson({}); | ^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4900,8 +4712,6 @@ error: struct "InflightStruct" must be declared at the top-level of a file 58 | struct InflightStruct { | ^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4957,8 +4767,6 @@ error: \`super\` calls inside inflight closures not supported yet, see: https:// 52 | return "this: {this.m1()}, super: {super.m1()}"; | ^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4972,8 +4780,6 @@ exports[`this.w 1`] = ` 3 | log(this.node.id); | ^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4987,8 +4793,6 @@ exports[`throw_non_string.test.w 1`] = ` 1 | throw 42; | ^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -5009,8 +4813,6 @@ error: Unexpected parentheses in catch block. Use 'catch longError' instead of ' 10 | } catch (longError) { | ^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -5026,8 +4828,6 @@ exports[`try_no_catch_or_finally.test.w 1`] = ` 3 | | } | \\-^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -5062,8 +4862,6 @@ error: Expected type to be "num", but got "str" instead 15 | a += b; | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -5128,8 +4926,6 @@ error: Member "push" does not exist in "Array" 29 | recursive_ar.at(0).push(3); // Error: push doesn't exist in Array | ^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -5171,8 +4967,6 @@ error: Unable to infer type by usage, an explicit type annotation is required 2 | let somePromise = Promise{}; | ^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -5186,8 +4980,6 @@ exports[`unknown_field.test.w 1`] = ` 1 | std.String.a.b.c.fromJson(); | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -5201,8 +4993,6 @@ exports[`unknown_submodule.test.w 1`] = ` 1 | std.random.String.fromJson("hello"); | ^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -5279,8 +5069,6 @@ error: Member "methodWhichIsNotPartOfBucketApi" does not exist in "Bucket" 23 | return this.bucket.methodWhichIsNotPartOfBucketApi(id); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -5357,8 +5145,6 @@ error: Unphased methods on interfaces are not yet supported - see https://github 33 | | } | \\-^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -5394,8 +5180,6 @@ error: Symbol "x" used before being defined 8 | let x = "hi"; | - defined later here - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -5409,8 +5193,6 @@ exports[`variable_scoping.test.w 1`] = ` 6 | let z = x; | ^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -5461,8 +5243,6 @@ error: Expected type to be "str?", but got "void" instead 15 | let w: str? = returnsNothing2(); | ^^^^^^^^^^^^^^^^^ - - Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) diff --git a/tools/hangar/__snapshots__/package-manager.ts.snap b/tools/hangar/__snapshots__/package-manager.ts.snap new file mode 100644 index 00000000000..56ccb70dc76 --- /dev/null +++ b/tools/hangar/__snapshots__/package-manager.ts.snap @@ -0,0 +1,5 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`warning is emitted when an unsupported package manager is used 1`] = `""`; + +exports[`warning is emitted when an unsupported package manager is used 2`] = `"warning: The current project has a pnpm/yarn/bun lockfile. Wing hasn't been tested with package managers besides npm, so it may be unable to resolve dependencies to Wing libraries when using these tools. See https://github.com/winglang/wing/issues/6129 for more details."`; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/debug_env.test.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/debug_env.test.w_compile_tf-aws.md deleted file mode 100644 index bda8b756ec9..00000000000 --- a/tools/hangar/__snapshots__/test_corpus/valid/debug_env.test.w_compile_tf-aws.md +++ /dev/null @@ -1,77 +0,0 @@ -# [debug_env.test.w](../../../../../examples/tests/valid/debug_env.test.w) | compile | tf-aws - -## inflight.A-1.cjs -```cjs -"use strict"; -const $helpers = require("@winglang/sdk/lib/helpers"); -const $macros = require("@winglang/sdk/lib/macros"); -module.exports = function({ }) { - class A { - } - return A; -} -//# sourceMappingURL=inflight.A-1.cjs.map -``` - -## main.tf.json -```json -{ - "//": { - "metadata": { - "backend": "local", - "stackName": "root" - }, - "outputs": {} - }, - "provider": { - "aws": [ - {} - ] - } -} -``` - -## preflight.cjs -```cjs -"use strict"; -const $stdlib = require('@winglang/sdk'); -const $macros = require("@winglang/sdk/lib/macros"); -const $platforms = ((s) => !s ? [] : s.split(';'))(process.env.WING_PLATFORMS); -const $outdir = process.env.WING_SYNTH_DIR ?? "."; -const $wing_is_test = process.env.WING_IS_TEST === "true"; -const std = $stdlib.std; -const $helpers = $stdlib.helpers; -const $extern = $helpers.createExternRequire(__dirname); -const $PlatformManager = new $stdlib.platform.PlatformManager({platformPaths: $platforms}); -class $Root extends $stdlib.std.Resource { - constructor($scope, $id) { - super($scope, $id); - $helpers.nodeof(this).root.$preflightTypesMap = { }; - let $preflightTypesMap = {}; - const cloud = $stdlib.cloud; - $helpers.nodeof(this).root.$preflightTypesMap = $preflightTypesMap; - class A extends $stdlib.std.Resource { - constructor($scope, $id, ) { - super($scope, $id); - this.b = globalThis.$ClassFactory.new("@winglang/sdk.cloud.Bucket", cloud.Bucket, this, "Bucket"); - } - static _toInflightType() { - return ` - require("${$helpers.normalPath(__dirname)}/inflight.A-1.cjs")({ - }) - `; - } - get _liftMap() { - return ({ - "$inflight_init": [ - ], - }); - } - } - } -} -const $APP = $PlatformManager.createApp({ outdir: $outdir, name: "debug_env.test", rootConstruct: $Root, isTestEnvironment: $wing_is_test, entrypointDir: process.env['WING_SOURCE_DIR'], rootId: process.env['WING_ROOT_ID'] }); -$APP.synth(); -//# sourceMappingURL=preflight.cjs.map -``` - diff --git a/tools/hangar/__snapshots__/test_corpus/valid/debug_env.test.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/debug_env.test.w_test_sim.md deleted file mode 100644 index 22535dcf374..00000000000 --- a/tools/hangar/__snapshots__/test_corpus/valid/debug_env.test.w_test_sim.md +++ /dev/null @@ -1,19 +0,0 @@ -# [debug_env.test.w](../../../../../examples/tests/valid/debug_env.test.w) | test | sim - -## stderr.log -```log -[symbol environment at debug_env.test.w:7:5] -level 0: { this => A } -level 1: { A => A [type], assert => (condition: bool, message: str?): void, cloud => cloud [namespace], log => (value: stringable): void, nodeof => preflight (construct: IConstruct): Node, std => std [namespace], this => Construct, unsafeCast => (value: any): any } -``` - -## stdout.log -```log -pass ─ debug_env.test.wsim (no tests) - -Tests 1 passed (1) -Snapshots 1 skipped -Test Files 1 passed (1) -Duration -``` - diff --git a/tools/hangar/src/invalid.test.ts b/tools/hangar/src/invalid.test.ts index 59b3c652616..360a749c3f6 100644 --- a/tools/hangar/src/invalid.test.ts +++ b/tools/hangar/src/invalid.test.ts @@ -31,10 +31,6 @@ invalidWingFiles.forEach((wingFile) => { }); expect(out.stdout).toMatchSnapshot(); - // when this env var is on, we allow the on-demand-panic-char (😱), right now panic writes to stderr (will be changed in the future) - if (metaComment?.env?.WINGC_DEBUG_PANIC) { - expect(out.stderr).toMatchSnapshot(); - } }); }); diff --git a/tools/hangar/src/package-manager.test.ts b/tools/hangar/src/package-manager.test.ts new file mode 100644 index 00000000000..294d485b6a0 --- /dev/null +++ b/tools/hangar/src/package-manager.test.ts @@ -0,0 +1,27 @@ +import { expect, test } from "vitest"; +import * as path from "path"; +import { validTestDir } from "./paths"; +import { mkdtemp, writeFile, copyFile } from "fs/promises"; +import { tmpdir } from "os"; +import { runWingCommand } from "./utils"; + +test("warning is emitted when an unsupported package manager is used", async () => { + const wingFile = "hello.test.w"; + const tmpDir = await mkdtemp(path.join(tmpdir(), "wing-test-")); + await copyFile( + path.join(validTestDir, wingFile), + path.join(tmpDir, wingFile) + ); + await writeFile(path.join(tmpDir, "yarn.lock"), "fake lock file"); + + const out = await runWingCommand({ + cwd: tmpDir, + wingFile: wingFile, + platforms: ["sim"], + args: ["compile"], + expectFailure: true, + }); + + expect(out.stdout).toMatchSnapshot(); + expect(out.stderr).toMatchSnapshot(); +});