diff --git a/crates/oxc_ast/src/ast/ts.rs b/crates/oxc_ast/src/ast/ts.rs index ca826a9ffaad7..2c02efb7578a2 100644 --- a/crates/oxc_ast/src/ast/ts.rs +++ b/crates/oxc_ast/src/ast/ts.rs @@ -1339,7 +1339,16 @@ impl<'a> Modifiers<'a> { .map_or(false, |modifiers| modifiers.iter().any(|modifier| modifier.kind == target)) } - pub fn find(&self, f: F) -> Option<&Modifier> + pub fn iter(&self) -> impl Iterator + '_ { + self.0.as_ref().into_iter().flat_map(|modifiers| modifiers.iter()) + } + + /// Find a modifier by kind + pub fn find(&self, kind: ModifierKind) -> Option<&Modifier> { + self.find_where(|modifier| modifier.kind == kind) + } + + pub fn find_where(&self, f: F) -> Option<&Modifier> where F: Fn(&Modifier) -> bool, { diff --git a/crates/oxc_linter/src/rules/oxc/no_const_enum.rs b/crates/oxc_linter/src/rules/oxc/no_const_enum.rs index 4e1151842c595..ac57a0983c129 100644 --- a/crates/oxc_linter/src/rules/oxc/no_const_enum.rs +++ b/crates/oxc_linter/src/rules/oxc/no_const_enum.rs @@ -41,8 +41,9 @@ declare_oxc_lint!( impl Rule for NoConstEnum { fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { if let AstKind::TSEnumDeclaration(enum_decl) = node.kind() { - let Some(const_enum) = - enum_decl.modifiers.find(|modifier| matches!(modifier.kind, ModifierKind::Const)) + let Some(const_enum) = enum_decl + .modifiers + .find_where(|modifier| matches!(modifier.kind, ModifierKind::Const)) else { return; }; diff --git a/crates/oxc_semantic/src/checker/mod.rs b/crates/oxc_semantic/src/checker/mod.rs index 0e0cef768dcd9..6a726abf5ab00 100644 --- a/crates/oxc_semantic/src/checker/mod.rs +++ b/crates/oxc_semantic/src/checker/mod.rs @@ -34,6 +34,7 @@ pub fn check<'a>(node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) { AstKind::RegExpLiteral(lit) => js::check_regexp_literal(lit, ctx), AstKind::Directive(dir) => js::check_directive(dir, ctx), + AstKind::Function(func) => ts::check_function(func, node, ctx), AstKind::ModuleDeclaration(decl) => { js::check_module_declaration(decl, node, ctx); } @@ -68,8 +69,10 @@ pub fn check<'a>(node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) { js::check_function_declaration(alternate, true, ctx); } } - - AstKind::Class(class) => js::check_class(class, node, ctx), + AstKind::Class(class) => { + js::check_class(class, node, ctx); + ts::check_class(class, node, ctx); + } AstKind::MethodDefinition(method) => js::check_method_definition(method, ctx), AstKind::ObjectProperty(prop) => js::check_object_property(prop, ctx), AstKind::Super(sup) => js::check_super(sup, node, ctx), @@ -91,13 +94,20 @@ pub fn check<'a>(node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) { AstKind::ObjectExpression(expr) => js::check_object_expression(expr, ctx), AstKind::UnaryExpression(expr) => js::check_unary_expression(expr, node, ctx), AstKind::YieldExpression(expr) => js::check_yield_expression(expr, node, ctx), + AstKind::VariableDeclaration(decl) => ts::check_variable_declaration(decl, node, ctx), AstKind::VariableDeclarator(decl) => ts::check_variable_declarator(decl, ctx), AstKind::SimpleAssignmentTarget(target) => ts::check_simple_assignment_target(target, ctx), AstKind::TSTypeParameterDeclaration(declaration) => { ts::check_ts_type_parameter_declaration(declaration, ctx); } - AstKind::TSModuleDeclaration(decl) => ts::check_ts_module_declaration(decl, ctx), - AstKind::TSEnumDeclaration(decl) => ts::check_ts_enum_declaration(decl, ctx), + AstKind::TSModuleDeclaration(decl) => ts::check_ts_module_declaration(decl, node, ctx), + AstKind::TSEnumDeclaration(decl) => ts::check_ts_enum_declaration(decl, node, ctx), + AstKind::TSTypeAliasDeclaration(decl) => { + ts::check_ts_type_alias_declaration(decl, node, ctx); + } + AstKind::TSInterfaceDeclaration(decl) => { + ts::check_ts_interface_declaration(decl, node, ctx); + } _ => {} } } diff --git a/crates/oxc_semantic/src/checker/typescript.rs b/crates/oxc_semantic/src/checker/typescript.rs index c387831957e36..d4143190a5d94 100644 --- a/crates/oxc_semantic/src/checker/typescript.rs +++ b/crates/oxc_semantic/src/checker/typescript.rs @@ -3,9 +3,10 @@ use oxc_ast::syntax_directed_operations::BoundNames; use oxc_ast::{ast::*, AstKind}; use oxc_diagnostics::OxcDiagnostic; use oxc_span::{Atom, GetSpan, Span}; +use oxc_syntax::scope::ScopeFlags; use rustc_hash::FxHashMap; -use crate::{builder::SemanticBuilder, diagnostics::redeclaration}; +use crate::{builder::SemanticBuilder, diagnostics::redeclaration, AstNode}; fn empty_type_parameter_list(span0: Span) -> OxcDiagnostic { OxcDiagnostic::error("Type parameter list cannot be empty.").with_labels([span0.into()]) @@ -23,7 +24,6 @@ pub fn check_ts_type_parameter_declaration( fn unexpected_optional(span0: Span) -> OxcDiagnostic { OxcDiagnostic::error("Unexpected `?` operator").with_labels([span0.into()]) } - #[allow(clippy::cast_possible_truncation)] pub fn check_variable_declarator(decl: &VariableDeclarator, ctx: &SemanticBuilder<'_>) { if decl.id.optional { @@ -114,6 +114,94 @@ pub fn check_array_pattern<'a>(pattern: &ArrayPattern<'a>, ctx: &SemanticBuilder } } +/// ts(1184) +fn modifiers_cannot_be_used_here(span: Span) -> OxcDiagnostic { + OxcDiagnostic::error("Modifiers cannot be used here.").with_labels([span.into()]) +} + +/// ts(1024) +fn readonly_only_on_index_signature_or_property_decl(span: Span) -> OxcDiagnostic { + OxcDiagnostic::error( + "'readonly' modifier can only appear on a property declaration or index signature.", + ) + .with_labels([span.into()]) +} +/// ts(1042) +fn async_cannot_be_used_here(span: Span) -> OxcDiagnostic { + OxcDiagnostic::error("'async' modifier cannot be used here.").with_labels([span.into()]) +} + +/// Returns `true` if the scope described by `scope_flags` supports export +/// declarations or specifiers. +pub const fn scope_can_export(scope_flags: ScopeFlags) -> bool { + const CAN_EXPORT: ScopeFlags = ScopeFlags::Top.union(ScopeFlags::TsModuleBlock); + scope_flags.contains(CAN_EXPORT) +} + +fn check_declaration_modifiers<'a>( + modifiers: &Modifiers<'a>, + decl_node: &AstNode<'a>, + ctx: &SemanticBuilder<'a>, +) { + let scope_flags = ctx.scope.get_flags(decl_node.scope_id()); + let kind = decl_node.kind(); + let is_class = matches!(kind, AstKind::Class(_)); + let is_function = matches!(kind, AstKind::Function(_)); + for modifier in modifiers.iter() { + match modifier.kind { + ModifierKind::Public + | ModifierKind::Private + | ModifierKind::Protected + | ModifierKind::Static + | ModifierKind::Override => { + ctx.error(modifiers_cannot_be_used_here(modifier.span)); + } + ModifierKind::Abstract if !is_class => { + ctx.error(modifiers_cannot_be_used_here(modifier.span)); + } + ModifierKind::Async if !is_function => { + ctx.error(async_cannot_be_used_here(modifier.span)); + } + ModifierKind::Readonly => { + ctx.error(readonly_only_on_index_signature_or_property_decl(modifier.span)); + } + ModifierKind::Export if !scope_can_export(scope_flags) => { + ctx.error(modifiers_cannot_be_used_here(modifier.span)); + } + _ => {} + } + } +} +pub fn check_variable_declaration<'a>( + decl: &VariableDeclaration<'a>, + node: &AstNode<'a>, + ctx: &SemanticBuilder<'a>, +) { + check_declaration_modifiers(&decl.modifiers, node, ctx); +} + +pub fn check_function<'a>(function: &Function<'a>, node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) { + check_declaration_modifiers(&function.modifiers, node, ctx); +} +pub fn check_class<'a>(class: &Class<'a>, node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) { + check_declaration_modifiers(&class.modifiers, node, ctx); +} + +pub fn check_ts_type_alias_declaration<'a>( + decl: &TSTypeAliasDeclaration<'a>, + node: &AstNode<'a>, + ctx: &SemanticBuilder<'a>, +) { + check_declaration_modifiers(&decl.modifiers, node, ctx); +} +pub fn check_ts_interface_declaration<'a>( + decl: &TSInterfaceDeclaration<'a>, + node: &AstNode<'a>, + ctx: &SemanticBuilder<'a>, +) { + check_declaration_modifiers(&decl.modifiers, node, ctx); +} + fn not_allowed_namespace_declaration(span0: Span) -> OxcDiagnostic { OxcDiagnostic::error( "A namespace declaration is only allowed at the top level of a namespace or module.", @@ -121,7 +209,12 @@ fn not_allowed_namespace_declaration(span0: Span) -> OxcDiagnostic { .with_labels([span0.into()]) } -pub fn check_ts_module_declaration<'a>(decl: &TSModuleDeclaration<'a>, ctx: &SemanticBuilder<'a>) { +pub fn check_ts_module_declaration<'a>( + decl: &TSModuleDeclaration<'a>, + node: &AstNode<'a>, + ctx: &SemanticBuilder<'a>, +) { + check_declaration_modifiers(&decl.modifiers, node, ctx); // skip current node for node in ctx.nodes.iter_parents(ctx.current_node_id).skip(1) { match node.kind() { @@ -144,8 +237,13 @@ fn enum_member_must_have_initializer(span0: Span) -> OxcDiagnostic { OxcDiagnostic::error("Enum member must have initializer.").with_labels([span0.into()]) } -pub fn check_ts_enum_declaration(decl: &TSEnumDeclaration<'_>, ctx: &SemanticBuilder<'_>) { +pub fn check_ts_enum_declaration<'a>( + decl: &TSEnumDeclaration<'a>, + node: &AstNode<'a>, + ctx: &SemanticBuilder<'a>, +) { let mut need_initializer = false; + check_declaration_modifiers(&decl.modifiers, node, ctx); decl.members.iter().for_each(|member| { #[allow(clippy::unnested_or_patterns)] diff --git a/crates/oxc_semantic/tests/integration/modules.rs b/crates/oxc_semantic/tests/integration/modules.rs index bd40ae95b66ef..1fed48fcff2b4 100644 --- a/crates/oxc_semantic/tests/integration/modules.rs +++ b/crates/oxc_semantic/tests/integration/modules.rs @@ -1,4 +1,4 @@ -use oxc_semantic::SymbolFlags; +use oxc_semantic::{SemanticBuilderReturn, SymbolFlags}; use crate::util::SemanticTester; @@ -46,6 +46,23 @@ fn test_exported_named_function() { .has_some_symbol("T") .is_not_exported() .test(); + + SemanticTester::tsx( + " + import React from 'react'; + export const Counter: React.FC<{ count: number }> = ({ count }) => ( +
{count}
+ ) + ", + ) + .has_some_symbol("Counter") + .is_exported() + .contains_flags( + SymbolFlags::ConstVariable + .union(SymbolFlags::BlockScopedVariable) + .union(SymbolFlags::Export), + ) + .test(); } #[test] @@ -149,3 +166,39 @@ fn test_exported_interface() { test.has_some_symbol("a").is_not_exported().test(); test.has_some_symbol("T").is_not_exported().test(); } + +#[test] +fn test_exports_in_namespace() { + let test = SemanticTester::ts( + " + export const x = 1; + namespace N { + function foo() { + return 1 + } + export function bar() { + return foo(); + } + export const x = 2 + } + ", + ); + test.has_some_symbol("bar").is_exported().test(); + let semantic = test.build(); + assert!(!semantic.module_record().exported_bindings.contains_key("bar")); +} + +#[test] +fn test_export_in_invalid_scope() { + let test = SemanticTester::js( + " + function foo() { + export const x = 1; + }", + ) + .expect_errors(true); + test.has_some_symbol("x").contains_flags(SymbolFlags::Export).test(); + let SemanticBuilderReturn { semantic, errors } = test.build_with_errors(); + assert!(!errors.is_empty(), "expected an export within a function to produce a check error, but no errors were produced"); + assert!(semantic.module_record().exported_bindings.is_empty()); +} diff --git a/crates/oxc_semantic/tests/integration/symbols.rs b/crates/oxc_semantic/tests/integration/symbols.rs index 8b43297749a19..9bc67699cfce2 100644 --- a/crates/oxc_semantic/tests/integration/symbols.rs +++ b/crates/oxc_semantic/tests/integration/symbols.rs @@ -114,3 +114,20 @@ fn test_export_flag() { tester.has_root_symbol("b").contains_flags(SymbolFlags::Export).test(); tester.has_root_symbol("c").contains_flags(SymbolFlags::Export).test(); } + +#[test] +fn test_invalid_modifiers() { + const PARAM_PROPERTY: &str = + "A parameter property is only allowed in a constructor implementation."; + const ILLEGAL_MODIFIER: &str = "Modifiers cannot be used here."; + const READONLY: &str = + "'readonly' modifier can only appear on a property declaration or index signature."; + + SemanticTester::ts("function foo(public x: number) { }").has_error(PARAM_PROPERTY); + // SemanticTester::ts("function foo() { export const x = 1; }").has_error(illegal_modifier); + SemanticTester::ts("function foo() { public const x = 1; }").has_error(ILLEGAL_MODIFIER); + SemanticTester::ts("function foo() { private const x = 1; }").has_error(ILLEGAL_MODIFIER); + SemanticTester::ts("function foo() { protected const x = 1; }").has_error(ILLEGAL_MODIFIER); + SemanticTester::ts("function foo() { abstract const x = 1; }").has_error(ILLEGAL_MODIFIER); + SemanticTester::ts("function foo() { readonly const x = 1; }").has_error(READONLY); +} diff --git a/crates/oxc_semantic/tests/integration/util/mod.rs b/crates/oxc_semantic/tests/integration/util/mod.rs index df4ea82b33458..3cdd9f154a059 100644 --- a/crates/oxc_semantic/tests/integration/util/mod.rs +++ b/crates/oxc_semantic/tests/integration/util/mod.rs @@ -9,7 +9,7 @@ use itertools::Itertools; use oxc_allocator::Allocator; use oxc_cfg::DisplayDot; use oxc_diagnostics::{Error, NamedSource, OxcDiagnostic}; -use oxc_semantic::{dot::DebugDot, Semantic, SemanticBuilder}; +use oxc_semantic::{dot::DebugDot, Semantic, SemanticBuilder, SemanticBuilderReturn}; use oxc_span::SourceType; pub use symbol_tester::SymbolTester; @@ -18,6 +18,10 @@ pub struct SemanticTester<'a> { source_type: SourceType, source_text: &'a str, cfg: bool, + /// Expect semantic analysis to produce errors. + /// + /// Default is `false`. + expect_errors: bool, } impl<'a> SemanticTester<'a> { @@ -28,6 +32,13 @@ impl<'a> SemanticTester<'a> { Self::new(source_text, SourceType::default().with_module(true).with_typescript(true)) } + /// Create a new tester for a TypeScript test case with JSX. + /// + /// Use [`SemanticTester::ts`] for TypeScript test cases without JSX. + pub fn tsx(source_text: &'static str) -> Self { + Self::ts(source_text).with_jsx(true) + } + /// Create a new tester for a JavaScript test case. /// /// Use [`SemanticTester::ts`] for TypeScript test cases. @@ -36,7 +47,13 @@ impl<'a> SemanticTester<'a> { } pub fn new(source_text: &'a str, source_type: SourceType) -> Self { - Self { allocator: Allocator::default(), source_type, source_text, cfg: false } + Self { + allocator: Allocator::default(), + source_type, + source_text, + cfg: false, + expect_errors: false, + } } /// Set the [`SourceType`] to TypeScript (or JavaScript, using `false`) @@ -64,11 +81,55 @@ impl<'a> SemanticTester<'a> { self.cfg = yes; self } + /// The program being tested is expected to produce errors during semantic analysis. + /// + /// By default, programs are expected to be error-free. + /// + /// # Example + /// ``` + /// use crate::util::{SemanticTester as T}; + /// + /// // Default behavior. You could omit `expect_errors(false)` here + /// T::js("function foo(a, a) { }").expect_errors(false).has_root_symbol("foo").test() + /// // Not allowed in TS + /// T::ts("function foo(a, a) { }").expect_errors(true).has_root_symbol("foo").test() + /// ``` + #[must_use] + pub fn expect_errors(mut self, yes: bool) -> Self { + self.expect_errors = yes; + self + } - /// Parse the source text and produce a new [`Semantic`] + /// Parse the source text and produce a new [`Semantic`]. + /// + /// Normally this will panic if semantic analysis produces any errors. Use /// # Panics + /// - if parsing fails + /// - if semantic analysis does/does not produce errors as expected #[allow(unstable_name_collisions)] pub fn build(&self) -> Semantic<'_> { + let semantic_ret = self.build_with_errors(); + match (self.expect_errors, semantic_ret.errors.is_empty()) { + (true, true) => panic!("Expected errors, but none were produced"), + (false, false) => panic!( + "Semantic analysis failed:\n\n{}", + semantic_ret + .errors + .iter() + .map(ToString::to_string) + .intersperse("\n\n".to_owned()) + .collect::() + ), + _ => semantic_ret.semantic, + } + } + + /// Parse the source text into a new [`Semantic`], but preserves any errors that occur during + /// semantic analysis + /// # Panics + /// + #[allow(unstable_name_collisions)] + pub fn build_with_errors(&self) -> SemanticBuilderReturn<'_> { let parse = oxc_parser::Parser::new(&self.allocator, self.source_text, self.source_type).parse(); @@ -85,25 +146,11 @@ impl<'a> SemanticTester<'a> { ); let program = self.allocator.alloc(parse.program); - let semantic_ret = SemanticBuilder::new(self.source_text, self.source_type) + SemanticBuilder::new(self.source_text, self.source_type) .with_check_syntax_error(true) .with_trivias(parse.trivias) .with_cfg(self.cfg) - .build(program); - - if !semantic_ret.errors.is_empty() { - let report = self.wrap_diagnostics(semantic_ret.errors); - panic!( - "Semantic analysis failed:\n\n{}", - report - .iter() - .map(ToString::to_string) - .intersperse("\n\n".to_owned()) - .collect::() - ); - }; - - semantic_ret.semantic + .build(program) } pub fn basic_blocks_count(&self) -> usize { @@ -150,6 +197,25 @@ impl<'a> SemanticTester<'a> { ClassTester::has_class(self.build(), name) } + pub fn has_error(&self, message: &str) { + let SemanticBuilderReturn { errors, .. } = self.build_with_errors(); + assert!( + !errors.is_empty(), + "Expected an error matching '{message}', but no errors were produced" + ); + if errors.iter().any(|e| e.message.contains(message)) { + return; + } + + let num_errors = errors.len(); + let rendered_errors = + self.wrap_diagnostics(errors).into_iter().map(|e| e.to_string()).join("\n\n"); + + panic!( + "Expected an error containing '{message}', but none of the {num_errors} matched:\n\n{rendered_errors}", + ) + } + /// Finds some symbol by name in the source code. /// /// ## Fails diff --git a/tasks/coverage/parser_babel.snap b/tasks/coverage/parser_babel.snap index 8a230e9f6685d..a7abecfc9a5ba 100644 --- a/tasks/coverage/parser_babel.snap +++ b/tasks/coverage/parser_babel.snap @@ -3,7 +3,7 @@ commit: 12619ffe parser_babel Summary: AST Parsed : 2095/2101 (99.71%) Positive Passed: 2087/2101 (99.33%) -Negative Passed: 1362/1501 (90.74%) +Negative Passed: 1364/1501 (90.87%) Expect Syntax Error: "annex-b/disabled/1.1-html-comments-close/input.js" Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions/input.js" Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions-if-body/input.js" @@ -96,8 +96,6 @@ Expect Syntax Error: "typescript/import/equals-in-script/input.ts" Expect Syntax Error: "typescript/import/equals-require-in-script/input.ts" Expect Syntax Error: "typescript/import/export-import-type/input.ts" Expect Syntax Error: "typescript/import/type-equals/input.ts" -Expect Syntax Error: "typescript/interface/abstract/input.ts" -Expect Syntax Error: "typescript/interface/export-abstract-interface/input.ts" Expect Syntax Error: "typescript/interface/get-set-invalid-optional-parameter/input.ts" Expect Syntax Error: "typescript/interface/get-set-invalid-optional-parameter-babel-7/input.ts" Expect Syntax Error: "typescript/interface/get-set-invalid-parameters/input.ts" @@ -10139,6 +10137,13 @@ Expect to Parse: "typescript/types/const-type-parameters-babel-7/input.ts" · ── ╰──── + × Modifiers cannot be used here. + ╭─[typescript/interface/abstract/input.ts:1:1] + 1 │ abstract interface Foo { + · ──────── + 2 │ foo: string; + ╰──── + × Expected a semicolon or an implicit semicolon after a statement, but found none ╭─[typescript/interface/declare-new-line/input.ts:1:8] 1 │ declare interface @@ -10147,6 +10152,13 @@ Expect to Parse: "typescript/types/const-type-parameters-babel-7/input.ts" ╰──── help: Try insert a semicolon here + × Modifiers cannot be used here. + ╭─[typescript/interface/export-abstract-interface/input.ts:1:8] + 1 │ export abstract interface I { + · ──────── + 2 │ + ╰──── + × Unexpected token ╭─[typescript/interface/export-default/input.ts:1:26] 1 │ export default interface {} diff --git a/tasks/coverage/parser_typescript.snap b/tasks/coverage/parser_typescript.snap index c50b0a0e8a836..b1384bc7b6711 100644 --- a/tasks/coverage/parser_typescript.snap +++ b/tasks/coverage/parser_typescript.snap @@ -3,7 +3,7 @@ commit: d8086f14 parser_typescript Summary: AST Parsed : 5280/5283 (99.94%) Positive Passed: 5273/5283 (99.81%) -Negative Passed: 1053/4875 (21.60%) +Negative Passed: 1073/4875 (22.01%) Expect Syntax Error: "compiler/ClassDeclaration10.ts" Expect Syntax Error: "compiler/ClassDeclaration11.ts" Expect Syntax Error: "compiler/ClassDeclaration13.ts" @@ -652,7 +652,6 @@ Expect Syntax Error: "compiler/exhaustiveSwitchCheckCircularity.ts" Expect Syntax Error: "compiler/exhaustiveSwitchImplicitReturn.ts" Expect Syntax Error: "compiler/expandoFunctionContextualTypesNoValue.ts" Expect Syntax Error: "compiler/expandoFunctionNestedAssigments.ts" -Expect Syntax Error: "compiler/exportAlreadySeen.ts" Expect Syntax Error: "compiler/exportAsNamespaceConflict.ts" Expect Syntax Error: "compiler/exportAssignmentWithExports.ts" Expect Syntax Error: "compiler/exportDeclarationsInAmbientNamespaces2.ts" @@ -755,7 +754,6 @@ Expect Syntax Error: "compiler/functionTypeArgumentArityErrors.ts" Expect Syntax Error: "compiler/functionTypeArgumentAssignmentCompat.ts" Expect Syntax Error: "compiler/functionVariableInReturnTypeAnnotation.ts" Expect Syntax Error: "compiler/functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts" -Expect Syntax Error: "compiler/functionsWithModifiersInBlocks1.ts" Expect Syntax Error: "compiler/fuzzy.ts" Expect Syntax Error: "compiler/generatorES6_5.ts" Expect Syntax Error: "compiler/generatorReturnExpressionIsChecked.ts" @@ -1409,7 +1407,6 @@ Expect Syntax Error: "compiler/primitiveTypeAsInterfaceName.ts" Expect Syntax Error: "compiler/primitiveTypeAsInterfaceNameGeneric.ts" Expect Syntax Error: "compiler/primitiveTypeAssignment.ts" Expect Syntax Error: "compiler/privacyGloImportParseErrors.ts" -Expect Syntax Error: "compiler/privacyImportParseErrors.ts" Expect Syntax Error: "compiler/privateAccessInSubclass1.ts" Expect Syntax Error: "compiler/privateFieldAssignabilityFromUnknown.ts" Expect Syntax Error: "compiler/privateInterfaceProperties.ts" @@ -1943,11 +1940,7 @@ Expect Syntax Error: "conformance/async/es5/asyncArrowFunction/asyncArrowFunctio Expect Syntax Error: "conformance/async/es5/asyncArrowFunction/asyncArrowFunction3_es5.ts" Expect Syntax Error: "conformance/async/es5/asyncArrowFunction/asyncArrowFunctionCapturesArguments_es5.ts" Expect Syntax Error: "conformance/async/es5/asyncAwaitIsolatedModules_es5.ts" -Expect Syntax Error: "conformance/async/es5/asyncClass_es5.ts" Expect Syntax Error: "conformance/async/es5/asyncDeclare_es5.ts" -Expect Syntax Error: "conformance/async/es5/asyncEnum_es5.ts" -Expect Syntax Error: "conformance/async/es5/asyncInterface_es5.ts" -Expect Syntax Error: "conformance/async/es5/asyncModule_es5.ts" Expect Syntax Error: "conformance/async/es5/functionDeclarations/asyncFunctionDeclaration13_es5.ts" Expect Syntax Error: "conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts" Expect Syntax Error: "conformance/async/es5/functionDeclarations/asyncFunctionDeclaration3_es5.ts" @@ -1956,11 +1949,7 @@ Expect Syntax Error: "conformance/async/es5/functionDeclarations/asyncFunctionDe Expect Syntax Error: "conformance/async/es6/asyncArrowFunction/asyncArrowFunction10_es6.ts" Expect Syntax Error: "conformance/async/es6/asyncArrowFunction/asyncArrowFunction3_es6.ts" Expect Syntax Error: "conformance/async/es6/asyncAwaitIsolatedModules_es6.ts" -Expect Syntax Error: "conformance/async/es6/asyncClass_es6.ts" Expect Syntax Error: "conformance/async/es6/asyncDeclare_es6.ts" -Expect Syntax Error: "conformance/async/es6/asyncEnum_es6.ts" -Expect Syntax Error: "conformance/async/es6/asyncInterface_es6.ts" -Expect Syntax Error: "conformance/async/es6/asyncModule_es6.ts" Expect Syntax Error: "conformance/async/es6/asyncQualifiedReturnType_es6.ts" Expect Syntax Error: "conformance/async/es6/await_unaryExpression_es6_1.ts" Expect Syntax Error: "conformance/async/es6/await_unaryExpression_es6_2.ts" @@ -1994,7 +1983,6 @@ Expect Syntax Error: "conformance/classes/classDeclarations/classAbstractKeyword Expect Syntax Error: "conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSuperCalls.ts" Expect Syntax Error: "conformance/classes/classDeclarations/classAbstractKeyword/classAbstractUsingAbstractMethod1.ts" Expect Syntax Error: "conformance/classes/classDeclarations/classAbstractKeyword/classAbstractUsingAbstractMethods2.ts" -Expect Syntax Error: "conformance/classes/classDeclarations/classAbstractKeyword/classAbstractWithInterface.ts" Expect Syntax Error: "conformance/classes/classDeclarations/classAndInterfaceMergeConflictingMembers.ts" Expect Syntax Error: "conformance/classes/classDeclarations/classExtendingClassLikeType.ts" Expect Syntax Error: "conformance/classes/classDeclarations/classExtendingNonConstructor.ts" @@ -2853,8 +2841,6 @@ Expect Syntax Error: "conformance/internalModules/exportDeclarations/ModuleWithE Expect Syntax Error: "conformance/internalModules/importDeclarations/circularImportAlias.ts" Expect Syntax Error: "conformance/internalModules/importDeclarations/invalidImportAliasIdentifiers.ts" Expect Syntax Error: "conformance/internalModules/importDeclarations/shadowedInternalModule.ts" -Expect Syntax Error: "conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts" -Expect Syntax Error: "conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts" Expect Syntax Error: "conformance/internalModules/moduleDeclarations/InvalidNonInstantiatedModule.ts" Expect Syntax Error: "conformance/internalModules/moduleDeclarations/invalidNestedModules.ts" Expect Syntax Error: "conformance/jsdoc/assertionsAndNonReturningFunctions.ts" @@ -3157,9 +3143,6 @@ Expect Syntax Error: "conformance/parser/ecmascript5/IndexSignatures/parserIndex Expect Syntax Error: "conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature5.ts" Expect Syntax Error: "conformance/parser/ecmascript5/InterfaceDeclarations/parserInterfaceDeclaration1.ts" Expect Syntax Error: "conformance/parser/ecmascript5/InterfaceDeclarations/parserInterfaceDeclaration2.ts" -Expect Syntax Error: "conformance/parser/ecmascript5/InterfaceDeclarations/parserInterfaceDeclaration3.ts" -Expect Syntax Error: "conformance/parser/ecmascript5/InterfaceDeclarations/parserInterfaceDeclaration4.ts" -Expect Syntax Error: "conformance/parser/ecmascript5/InterfaceDeclarations/parserInterfaceDeclaration6.ts" Expect Syntax Error: "conformance/parser/ecmascript5/InterfaceDeclarations/parserInterfaceDeclaration8.ts" Expect Syntax Error: "conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessor1.ts" Expect Syntax Error: "conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration1.ts" @@ -3192,8 +3175,6 @@ Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParame Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList2.ts" Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList7.ts" Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList8.ts" -Expect Syntax Error: "conformance/parser/ecmascript5/Protected/Protected1.ts" -Expect Syntax Error: "conformance/parser/ecmascript5/Protected/Protected2.ts" Expect Syntax Error: "conformance/parser/ecmascript5/Protected/Protected4.ts" Expect Syntax Error: "conformance/parser/ecmascript5/Protected/Protected6.ts" Expect Syntax Error: "conformance/parser/ecmascript5/Protected/Protected7.ts" @@ -3205,7 +3186,6 @@ Expect Syntax Error: "conformance/parser/ecmascript5/RegressionTests/parser50969 Expect Syntax Error: "conformance/parser/ecmascript5/RegressionTests/parser509698.ts" Expect Syntax Error: "conformance/parser/ecmascript5/RegressionTests/parser536727.ts" Expect Syntax Error: "conformance/parser/ecmascript5/RegressionTests/parser579071.ts" -Expect Syntax Error: "conformance/parser/ecmascript5/RegressionTests/parser618973.ts" Expect Syntax Error: "conformance/parser/ecmascript5/RegressionTests/parserTernaryAndCommaOperators1.ts" Expect Syntax Error: "conformance/parser/ecmascript5/RegularExpressions/parseRegularExpressionMixedWithComments.ts" Expect Syntax Error: "conformance/parser/ecmascript5/RegularExpressions/parserRegularExpression2.ts" @@ -6434,6 +6414,86 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" · ╰── `from` expected ╰──── + × Modifiers cannot be used here. + ╭─[compiler/exportAlreadySeen.ts:2:12] + 1 │ module M { + 2 │ export export var x = 1; + · ────── + 3 │ export export function f() { } + ╰──── + + × Modifiers cannot be used here. + ╭─[compiler/exportAlreadySeen.ts:3:12] + 2 │ export export var x = 1; + 3 │ export export function f() { } + · ────── + 4 │ + ╰──── + + × Modifiers cannot be used here. + ╭─[compiler/exportAlreadySeen.ts:6:16] + 5 │ export export module N { + 6 │ export export class C { } + · ────── + 7 │ export export interface I { } + ╰──── + + × Modifiers cannot be used here. + ╭─[compiler/exportAlreadySeen.ts:7:16] + 6 │ export export class C { } + 7 │ export export interface I { } + · ────── + 8 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[compiler/exportAlreadySeen.ts:5:12] + 4 │ + 5 │ export export module N { + · ────── + 6 │ export export class C { } + ╰──── + + × Modifiers cannot be used here. + ╭─[compiler/exportAlreadySeen.ts:12:12] + 11 │ declare module A { + 12 │ export export var x; + · ────── + 13 │ export export function f() + ╰──── + + × Modifiers cannot be used here. + ╭─[compiler/exportAlreadySeen.ts:13:12] + 12 │ export export var x; + 13 │ export export function f() + · ────── + 14 │ + ╰──── + + × Modifiers cannot be used here. + ╭─[compiler/exportAlreadySeen.ts:16:16] + 15 │ export export module N { + 16 │ export export class C { } + · ────── + 17 │ export export interface I { } + ╰──── + + × Modifiers cannot be used here. + ╭─[compiler/exportAlreadySeen.ts:17:16] + 16 │ export export class C { } + 17 │ export export interface I { } + · ────── + 18 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[compiler/exportAlreadySeen.ts:15:12] + 14 │ + 15 │ export export module N { + · ────── + 16 │ export export class C { } + ╰──── + × Unexpected token ╭─[compiler/exportAssignmentWithDeclareAndExportModifiers.ts:2:16] 1 │ var x; @@ -6683,6 +6743,14 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 154 │ } ╰──── + × Modifiers cannot be used here. + ╭─[compiler/functionsWithModifiersInBlocks1.ts:4:12] + 3 │ export function f() { } + 4 │ declare export function f() { } + · ────── + 5 │ } + ╰──── + × Unexpected token ╭─[compiler/genericCallWithoutArgs.ts:4:18] 3 │ @@ -8629,6 +8697,14 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 1 │ if (true) { ╰──── + × Modifiers cannot be used here. + ╭─[compiler/privacyImportParseErrors.ts:326:9] + 325 │ + 326 │ declare export module "anotherParseError2" { + · ────── + 327 │ module m2 { + ╰──── + × Unexpected token ╭─[compiler/privateNameJsx.tsx:4:22] 3 │ render() { @@ -10592,6 +10668,13 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 2 │ } ╰──── + × 'async' modifier cannot be used here. + ╭─[conformance/async/es5/asyncClass_es5.ts:1:1] + 1 │ async class C { + · ───── + 2 │ } + ╰──── + × Constructor can't be an async method ╭─[conformance/async/es5/asyncConstructor_es5.ts:2:9] 1 │ class C { @@ -10600,6 +10683,13 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 3 │ } ╰──── + × 'async' modifier cannot be used here. + ╭─[conformance/async/es5/asyncEnum_es5.ts:1:1] + 1 │ async enum E { + · ───── + 2 │ Value + ╰──── + × Expected `(` but found `Identifier` ╭─[conformance/async/es5/asyncGetter_es5.ts:2:13] 1 │ class C { @@ -10609,6 +10699,20 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 3 │ } ╰──── + × 'async' modifier cannot be used here. + ╭─[conformance/async/es5/asyncInterface_es5.ts:1:1] + 1 │ async interface I { + · ───── + 2 │ } + ╰──── + + × 'async' modifier cannot be used here. + ╭─[conformance/async/es5/asyncModule_es5.ts:1:1] + 1 │ async module M { + · ───── + 2 │ } + ╰──── + × Expected `(` but found `Identifier` ╭─[conformance/async/es5/asyncSetter_es5.ts:2:13] 1 │ class C { @@ -10699,6 +10803,13 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 2 │ } ╰──── + × 'async' modifier cannot be used here. + ╭─[conformance/async/es6/asyncClass_es6.ts:1:1] + 1 │ async class C { + · ───── + 2 │ } + ╰──── + × Constructor can't be an async method ╭─[conformance/async/es6/asyncConstructor_es6.ts:2:9] 1 │ class C { @@ -10707,6 +10818,13 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 3 │ } ╰──── + × 'async' modifier cannot be used here. + ╭─[conformance/async/es6/asyncEnum_es6.ts:1:1] + 1 │ async enum E { + · ───── + 2 │ Value + ╰──── + × Expected `(` but found `Identifier` ╭─[conformance/async/es6/asyncGetter_es6.ts:2:13] 1 │ class C { @@ -10716,6 +10834,20 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 3 │ } ╰──── + × 'async' modifier cannot be used here. + ╭─[conformance/async/es6/asyncInterface_es6.ts:1:1] + 1 │ async interface I { + · ───── + 2 │ } + ╰──── + + × 'async' modifier cannot be used here. + ╭─[conformance/async/es6/asyncModule_es6.ts:1:1] + 1 │ async module M { + · ───── + 2 │ } + ╰──── + × Expected `(` but found `Identifier` ╭─[conformance/async/es6/asyncSetter_es6.ts:2:13] 1 │ class C { @@ -10873,6 +11005,12 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 17 │ } ╰──── + × Modifiers cannot be used here. + ╭─[conformance/classes/classDeclarations/classAbstractKeyword/classAbstractWithInterface.ts:1:1] + 1 │ abstract interface I {} + · ──────── + ╰──── + × Identifier `C` has already been declared ╭─[conformance/classes/classDeclarations/classAndVariableWithSameName.ts:1:7] 1 │ class C { foo: string; } // error @@ -16067,6 +16205,222 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 3 │ let; ╰──── + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:4:5] + 3 │ module Y { + 4 │ public class A { s: string } + · ────── + 5 │ + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:6:5] + 5 │ + 6 │ public class BB extends A { + · ────── + 7 │ id: number; + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:12:5] + 11 │ module Y2 { + 12 │ public class AA { s: T } + · ────── + 13 │ public interface I { id: number } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:13:5] + 12 │ public class AA { s: T } + 13 │ public interface I { id: number } + · ────── + 14 │ + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:15:5] + 14 │ + 15 │ public class B extends AA implements I { id: number } + · ────── + 16 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:19:5] + 18 │ module Y3 { + 19 │ public module Module { + · ────── + 20 │ class A { s: string } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:25:5] + 24 │ module Y4 { + 25 │ public enum Color { Blue, Red } + · ────── + 26 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:29:5] + 28 │ module YY { + 29 │ private class A { s: string } + · ─────── + 30 │ + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:31:5] + 30 │ + 31 │ private class BB extends A { + · ─────── + 32 │ id: number; + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:37:5] + 36 │ module YY2 { + 37 │ private class AA { s: T } + · ─────── + 38 │ private interface I { id: number } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:38:5] + 37 │ private class AA { s: T } + 38 │ private interface I { id: number } + · ─────── + 39 │ + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:40:5] + 39 │ + 40 │ private class B extends AA implements I { id: number } + · ─────── + 41 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:44:5] + 43 │ module YY3 { + 44 │ private module Module { + · ─────── + 45 │ class A { s: string } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:50:5] + 49 │ module YY4 { + 50 │ private enum Color { Blue, Red } + · ─────── + 51 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:55:5] + 54 │ module YYY { + 55 │ static class A { s: string } + · ────── + 56 │ + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:57:5] + 56 │ + 57 │ static class BB extends A { + · ────── + 58 │ id: number; + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:63:5] + 62 │ module YYY2 { + 63 │ static class AA { s: T } + · ────── + 64 │ static interface I { id: number } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:64:5] + 63 │ static class AA { s: T } + 64 │ static interface I { id: number } + · ────── + 65 │ + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:66:5] + 65 │ + 66 │ static class B extends AA implements I { id: number } + · ────── + 67 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:70:5] + 69 │ module YYY3 { + 70 │ static module Module { + · ────── + 71 │ class A { s: string } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:76:5] + 75 │ module YYY4 { + 76 │ static enum Color { Blue, Red } + · ────── + 77 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts:4:5] + 3 │ module Y { + 4 │ public var x: number = 0; + · ────── + 5 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts:8:5] + 7 │ module Y2 { + 8 │ public function fn(x: string) { } + · ────── + 9 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts:12:5] + 11 │ module Y4 { + 12 │ static var x: number = 0; + · ────── + 13 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts:16:5] + 15 │ module YY { + 16 │ static function fn(x: string) { } + · ────── + 17 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts:20:5] + 19 │ module YY2 { + 20 │ private var x: number = 0; + · ─────── + 21 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts:25:5] + 24 │ module YY3 { + 25 │ private function fn(x: string) { } + · ─────── + 26 │ } + ╰──── + × Identifier `Point` has already been declared ╭─[conformance/internalModules/moduleDeclarations/invalidInstantiatedModule.ts:2:18] 1 │ module M { @@ -17154,6 +17508,27 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 3 │ } ╰──── + × Modifiers cannot be used here. + ╭─[conformance/parser/ecmascript5/InterfaceDeclarations/parserInterfaceDeclaration3.ts:1:1] + 1 │ public interface I { + · ────── + 2 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/parser/ecmascript5/InterfaceDeclarations/parserInterfaceDeclaration4.ts:1:1] + 1 │ static interface I { + · ────── + 2 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/parser/ecmascript5/InterfaceDeclarations/parserInterfaceDeclaration6.ts:1:8] + 1 │ export export interface I { + · ────── + 2 │ } + ╰──── + × Expected a semicolon or an implicit semicolon after a statement, but found none ╭─[conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration10.ts:2:11] 1 │ class C { @@ -17376,6 +17751,20 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 3 │ } ╰──── + × Modifiers cannot be used here. + ╭─[conformance/parser/ecmascript5/Protected/Protected1.ts:1:1] + 1 │ protected class C { + · ───────── + 2 │ } + ╰──── + + × Modifiers cannot be used here. + ╭─[conformance/parser/ecmascript5/Protected/Protected2.ts:1:1] + 1 │ protected module M { + · ───────── + 2 │ } + ╰──── + × Expected a semicolon or an implicit semicolon after a statement, but found none ╭─[conformance/parser/ecmascript5/RealWorld/parserharness.ts:1430:16] 1429 │ // Regex for parsing options in the format "@Alpha: Value of any sort" @@ -17466,6 +17855,13 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" ╰──── help: Try insert a semicolon here + × Modifiers cannot be used here. + ╭─[conformance/parser/ecmascript5/RegressionTests/parser618973.ts:1:8] + 1 │ export export class Foo { + · ────── + 2 │ public Bar() { + ╰──── + × The keyword 'static' is reserved ╭─[conformance/parser/ecmascript5/RegressionTests/parser642331.ts:2:18] 1 │ class test {