diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 65677ea034ada..36059acf61a81 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -19,6 +19,7 @@ import { JSDocSyntaxKind, JsxTokenSyntaxKind, KeywordSyntaxKind, + LanguageFeatureMinimumTarget, LanguageVariant, last, LineAndCharacter, @@ -293,15 +294,12 @@ const charToRegExpFlag = new Map(Object.entries({ y: RegularExpressionFlags.Sticky, })); -const regExpFlagToFirstAvailableLanguageVersion = new Map([ - [RegularExpressionFlags.HasIndices, ScriptTarget.ES2022], - [RegularExpressionFlags.Global, ScriptTarget.ES3], - [RegularExpressionFlags.IgnoreCase, ScriptTarget.ES3], - [RegularExpressionFlags.Multiline, ScriptTarget.ES3], - [RegularExpressionFlags.DotAll, ScriptTarget.ES2018], - [RegularExpressionFlags.Unicode, ScriptTarget.ES2015], - [RegularExpressionFlags.UnicodeSets, ScriptTarget.ESNext], - [RegularExpressionFlags.Sticky, ScriptTarget.ES2015], +const regExpFlagToFirstAvailableLanguageVersion = new Map([ + [RegularExpressionFlags.HasIndices, LanguageFeatureMinimumTarget.RegularExpressionFlagsHasIndices], + [RegularExpressionFlags.DotAll, LanguageFeatureMinimumTarget.RegularExpressionFlagsDotAll], + [RegularExpressionFlags.Unicode, LanguageFeatureMinimumTarget.RegularExpressionFlagsUnicode], + [RegularExpressionFlags.UnicodeSets, LanguageFeatureMinimumTarget.RegularExpressionFlagsUnicodeSets], + [RegularExpressionFlags.Sticky, LanguageFeatureMinimumTarget.RegularExpressionFlagsSticky], ]); /* @@ -2461,10 +2459,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean } else { regExpFlags |= flag; - const availableFrom = regExpFlagToFirstAvailableLanguageVersion.get(flag)!; - if (languageVersion < availableFrom) { - error(Diagnostics.This_regular_expression_flag_is_only_available_when_targeting_0_or_later, p, 1, getNameOfScriptTarget(availableFrom)); - } + checkRegularExpressionFlagAvailable(flag, p); } } p++; @@ -2742,10 +2737,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean } else { currFlags |= flag; - const availableFrom = regExpFlagToFirstAvailableLanguageVersion.get(flag)!; - if (languageVersion < availableFrom) { - error(Diagnostics.This_regular_expression_flag_is_only_available_when_targeting_0_or_later, pos, 1, getNameOfScriptTarget(availableFrom)); - } + checkRegularExpressionFlagAvailable(flag, pos); } pos++; } @@ -3446,6 +3438,13 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean } }); } + + function checkRegularExpressionFlagAvailable(flag: RegularExpressionFlags, pos: number) { + const availableFrom = regExpFlagToFirstAvailableLanguageVersion.get(flag) as ScriptTarget | undefined; + if (availableFrom && languageVersion < availableFrom) { + error(Diagnostics.This_regular_expression_flag_is_only_available_when_targeting_0_or_later, pos, 1, getNameOfScriptTarget(availableFrom)); + } + } } function appendIfCommentDirective( diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 70397a75908de..76f8193ae127d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8231,6 +8231,8 @@ export const enum LanguageFeatureMinimumTarget { ArrowFunctions = ScriptTarget.ES2015, BlockScopedVariables = ScriptTarget.ES2015, ObjectAssign = ScriptTarget.ES2015, + RegularExpressionFlagsUnicode = ScriptTarget.ES2015, + RegularExpressionFlagsSticky = ScriptTarget.ES2015, // ES2016 Features Exponentiation = ScriptTarget.ES2016, // `x ** y` @@ -8243,6 +8245,7 @@ export const enum LanguageFeatureMinimumTarget { AsyncGenerators = ScriptTarget.ES2018, // `async function * f() { }` AsyncIteration = ScriptTarget.ES2018, // `Symbol.asyncIterator` ObjectSpreadRest = ScriptTarget.ES2018, // `{ ...obj }` + RegularExpressionFlagsDotAll = ScriptTarget.ES2018, // ES2019 Features BindinglessCatch = ScriptTarget.ES2019, // `try { } catch { }` @@ -8259,6 +8262,7 @@ export const enum LanguageFeatureMinimumTarget { TopLevelAwait = ScriptTarget.ES2022, ClassFields = ScriptTarget.ES2022, PrivateNamesAndClassStaticBlocks = ScriptTarget.ES2022, // `class C { static {} #x = y, #m() {} }`, `#x in y` + RegularExpressionFlagsHasIndices = ScriptTarget.ES2022, // ES2023 Features ShebangComments = ScriptTarget.ESNext, @@ -8269,6 +8273,7 @@ export const enum LanguageFeatureMinimumTarget { // transformers/esnext.ts, commandLineParser.ts, and the contents of each lib/esnext.*.d.ts file. UsingAndAwaitUsing = ScriptTarget.ESNext, // `using x = y`, `await using x = y` ClassAndClassElementDecorators = ScriptTarget.ESNext, // `@dec class C {}`, `class C { @dec m() {} }` + RegularExpressionFlagsUnicodeSets = ScriptTarget.ESNext, } // dprint-ignore