From e96f25b44c0d186424bc4547705564b7360cea89 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:49:19 -0700 Subject: [PATCH 1/5] Move RegExp flag version mapping to LanguageFeatureMinimumTarget --- src/compiler/scanner.ts | 23 ++++++++++++----------- src/compiler/types.ts | 10 ++++++++++ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 01dc3b1b31494..b0b2a4b7de5d2 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -19,6 +19,7 @@ import { JSDocSyntaxKind, JsxTokenSyntaxKind, KeywordSyntaxKind, + LanguageFeatureMinimumTarget, LanguageVariant, last, LineAndCharacter, @@ -291,15 +292,15 @@ 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.Global, LanguageFeatureMinimumTarget.RegularExpressionFlagsGlobal], + [RegularExpressionFlags.IgnoreCase, LanguageFeatureMinimumTarget.RegularExpressionFlagsIgnoreCase], + [RegularExpressionFlags.Multiline, LanguageFeatureMinimumTarget.RegularExpressionFlagsMultiline], + [RegularExpressionFlags.DotAll, LanguageFeatureMinimumTarget.RegularExpressionFlagsDotAll], + [RegularExpressionFlags.Unicode, LanguageFeatureMinimumTarget.RegularExpressionFlagsUnicode], + [RegularExpressionFlags.UnicodeSets, LanguageFeatureMinimumTarget.RegularExpressionFlagsUnicodeSets], + [RegularExpressionFlags.Sticky, LanguageFeatureMinimumTarget.RegularExpressionFlagsSticky], ]); /* @@ -2456,7 +2457,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean } else { regExpFlags |= flag; - const availableFrom = regExpFlagToFirstAvailableLanguageVersion.get(flag)!; + const availableFrom = regExpFlagToFirstAvailableLanguageVersion.get(flag)! as unknown as ScriptTarget; if (languageVersion < availableFrom) { error(Diagnostics.This_regular_expression_flag_is_only_available_when_targeting_0_or_later, p, 1, getNameOfScriptTarget(availableFrom)); } @@ -2724,7 +2725,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean } else { currFlags |= flag; - const availableFrom = regExpFlagToFirstAvailableLanguageVersion.get(flag)!; + const availableFrom = regExpFlagToFirstAvailableLanguageVersion.get(flag)! as unknown as ScriptTarget; if (languageVersion < availableFrom) { error(Diagnostics.This_regular_expression_flag_is_only_available_when_targeting_0_or_later, pos, 1, getNameOfScriptTarget(availableFrom)); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 70397a75908de..d226e2b7af14e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8218,6 +8218,11 @@ export type EmitHelperUniqueNameCallback = (name: string) => string; * @internal */ export const enum LanguageFeatureMinimumTarget { + // ES3 Features + RegularExpressionFlagsGlobal = ScriptTarget.ES3, + RegularExpressionFlagsIgnoreCase = ScriptTarget.ES3, + RegularExpressionFlagsMultiline = ScriptTarget.ES3, + // ES2015 Features Classes = ScriptTarget.ES2015, ForOf = ScriptTarget.ES2015, @@ -8231,6 +8236,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 +8250,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,9 +8267,11 @@ 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, + RegularExpressionFlagsUnicodeSets = ScriptTarget.ESNext, // Upcoming Features // NOTE: We must reevaluate the target for upcoming features when each successive TC39 edition is ratified in From d8d83acff8cd41c03fa2bb336f98ae3c0eca79c6 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 24 Apr 2024 20:48:47 -0700 Subject: [PATCH 2/5] Move to es2024 --- src/compiler/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d226e2b7af14e..5134069cf6710 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8271,7 +8271,6 @@ export const enum LanguageFeatureMinimumTarget { // ES2023 Features ShebangComments = ScriptTarget.ESNext, - RegularExpressionFlagsUnicodeSets = ScriptTarget.ESNext, // Upcoming Features // NOTE: We must reevaluate the target for upcoming features when each successive TC39 edition is ratified in @@ -8279,6 +8278,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 From d7fc5b091ce2d96452f24fcd90bc423dad03cf9d Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 25 Apr 2024 12:30:43 -0700 Subject: [PATCH 3/5] Fix ups --- src/compiler/scanner.ts | 15 ++++++++------- src/compiler/types.ts | 5 ----- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index c7eb40fd15c93..5e5fe2f54af1a 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -296,15 +296,16 @@ const charToRegExpFlag = new Map(Object.entries({ const regExpFlagToFirstAvailableLanguageVersion = new Map([ [RegularExpressionFlags.HasIndices, LanguageFeatureMinimumTarget.RegularExpressionFlagsHasIndices], - [RegularExpressionFlags.Global, LanguageFeatureMinimumTarget.RegularExpressionFlagsGlobal], - [RegularExpressionFlags.IgnoreCase, LanguageFeatureMinimumTarget.RegularExpressionFlagsIgnoreCase], - [RegularExpressionFlags.Multiline, LanguageFeatureMinimumTarget.RegularExpressionFlagsMultiline], [RegularExpressionFlags.DotAll, LanguageFeatureMinimumTarget.RegularExpressionFlagsDotAll], [RegularExpressionFlags.Unicode, LanguageFeatureMinimumTarget.RegularExpressionFlagsUnicode], [RegularExpressionFlags.UnicodeSets, LanguageFeatureMinimumTarget.RegularExpressionFlagsUnicodeSets], [RegularExpressionFlags.Sticky, LanguageFeatureMinimumTarget.RegularExpressionFlagsSticky], ]); +function getRegExpFlagToFirstAvailableLanguageVersion(flag: RegularExpressionFlags) { + return regExpFlagToFirstAvailableLanguageVersion.get(flag) as ScriptTarget | undefined; +} + /* As per ECMAScript Language Specification 5th Edition, Section 7.6: ISyntaxToken Names and Identifiers IdentifierStart :: @@ -2462,8 +2463,8 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean } else { regExpFlags |= flag; - const availableFrom = regExpFlagToFirstAvailableLanguageVersion.get(flag)! as unknown as ScriptTarget; - if (languageVersion < availableFrom) { + const availableFrom = getRegExpFlagToFirstAvailableLanguageVersion(flag); + if (availableFrom && languageVersion < availableFrom) { error(Diagnostics.This_regular_expression_flag_is_only_available_when_targeting_0_or_later, p, 1, getNameOfScriptTarget(availableFrom)); } } @@ -2743,8 +2744,8 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean } else { currFlags |= flag; - const availableFrom = regExpFlagToFirstAvailableLanguageVersion.get(flag)! as unknown as ScriptTarget; - if (languageVersion < availableFrom) { + const availableFrom = getRegExpFlagToFirstAvailableLanguageVersion(flag); + if (availableFrom && languageVersion < availableFrom) { error(Diagnostics.This_regular_expression_flag_is_only_available_when_targeting_0_or_later, pos, 1, getNameOfScriptTarget(availableFrom)); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5134069cf6710..76f8193ae127d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8218,11 +8218,6 @@ export type EmitHelperUniqueNameCallback = (name: string) => string; * @internal */ export const enum LanguageFeatureMinimumTarget { - // ES3 Features - RegularExpressionFlagsGlobal = ScriptTarget.ES3, - RegularExpressionFlagsIgnoreCase = ScriptTarget.ES3, - RegularExpressionFlagsMultiline = ScriptTarget.ES3, - // ES2015 Features Classes = ScriptTarget.ES2015, ForOf = ScriptTarget.ES2015, From d18423bdbe758a2123f255b656a020322dfcc5db Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 25 Apr 2024 14:18:47 -0700 Subject: [PATCH 4/5] Share code --- src/compiler/scanner.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 5e5fe2f54af1a..8723a269ec9ca 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -2463,10 +2463,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean } else { regExpFlags |= flag; - const availableFrom = getRegExpFlagToFirstAvailableLanguageVersion(flag); - if (availableFrom && languageVersion < availableFrom) { - error(Diagnostics.This_regular_expression_flag_is_only_available_when_targeting_0_or_later, p, 1, getNameOfScriptTarget(availableFrom)); - } + checkRegularExpressionFlagAvailable(flag, p); } } p++; @@ -2744,10 +2741,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean } else { currFlags |= flag; - const availableFrom = getRegExpFlagToFirstAvailableLanguageVersion(flag); - if (availableFrom && languageVersion < availableFrom) { - error(Diagnostics.This_regular_expression_flag_is_only_available_when_targeting_0_or_later, pos, 1, getNameOfScriptTarget(availableFrom)); - } + checkRegularExpressionFlagAvailable(flag, pos); } pos++; } @@ -3448,6 +3442,13 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean } }); } + + function checkRegularExpressionFlagAvailable(flag: RegularExpressionFlags, pos: number) { + const availableFrom = getRegExpFlagToFirstAvailableLanguageVersion(flag); + if (availableFrom && languageVersion < availableFrom) { + error(Diagnostics.This_regular_expression_flag_is_only_available_when_targeting_0_or_later, pos, 1, getNameOfScriptTarget(availableFrom)); + } + } } function appendIfCommentDirective( From fb5e02be2fb88f4f472d65be5672ca108fc01259 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 25 Apr 2024 14:19:02 -0700 Subject: [PATCH 5/5] remove func --- src/compiler/scanner.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 8723a269ec9ca..36059acf61a81 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -302,10 +302,6 @@ const regExpFlagToFirstAvailableLanguageVersion = new Map