diff --git a/Makefile b/Makefile index dd41a0cb0918..03c40f65fa81 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ FLOW_COMMIT = a1f9a4c709dcebb27a5084acf47755fbae699c25 TEST262_COMMIT = 058adfed86b1d4129996faaf50a85ea55379a66a -TYPESCRIPT_COMMIT = 5fc917be2e4dd64c8e9504d36615cd7fbfdd4cd3 +TYPESCRIPT_COMMIT = ffa35d3272647fe48ddf173e1f0928f772c18630 FORCE_PUBLISH = "@babel/runtime,@babel/runtime-corejs2,@babel/runtime-corejs3,@babel/standalone" diff --git a/packages/babel-parser/src/parser/statement.js b/packages/babel-parser/src/parser/statement.js index 9bbed6ca25f1..224515cd76e2 100644 --- a/packages/babel-parser/src/parser/statement.js +++ b/packages/babel-parser/src/parser/statement.js @@ -636,6 +636,16 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "ThrowStatement"); } + parseCatchClauseParam(): N.Identifier { + const param = this.parseBindingAtom(); + + const simple = param.type === "Identifier"; + this.scope.enter(simple ? SCOPE_SIMPLE_CATCH : 0); + this.checkLVal(param, BIND_LEXICAL, null, "catch clause"); + + return param; + } + parseTryStatement(node: N.TryStatement): N.TryStatement { this.next(); @@ -647,10 +657,7 @@ export default class StatementParser extends ExpressionParser { this.next(); if (this.match(tt.parenL)) { this.expect(tt.parenL); - clause.param = this.parseBindingAtom(); - const simple = clause.param.type === "Identifier"; - this.scope.enter(simple ? SCOPE_SIMPLE_CATCH : 0); - this.checkLVal(clause.param, BIND_LEXICAL, null, "catch clause"); + clause.param = this.parseCatchClauseParam(); this.expect(tt.parenR); } else { clause.param = null; diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index 6309c8ea8fcb..14b0f3b97713 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -86,6 +86,8 @@ const TSErrors = Object.freeze({ "Template literal types cannot have any substitution", TypeAnnotationAfterAssign: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`", + UnexpectedCatchClauseParamType: + "Catch clause variable type annotation must be 'any' or 'unknown' if specified.", UnexpectedReadonly: "'readonly' type modifier is only permitted on array and tuple literal types.", UnexpectedTypeAnnotation: "Did not expect a type annotation here.", @@ -2667,4 +2669,26 @@ export default (superClass: Class): Class => return hasContextParam ? baseCount + 1 : baseCount; } + + parseCatchClauseParam(): N.Identifier { + const param = super.parseCatchClauseParam(); + const type = this.tsTryParseTypeAnnotation(); + + if (type) { + switch (type.typeAnnotation.type) { + case "TSAnyKeyword": + case "TSUnknownKeyword": + param.type = type; + break; + + default: + this.raise( + type.typeAnnotation.start, + TSErrors.UnexpectedCatchClauseParamType, + ); + } + } + + return param; + } }; diff --git a/packages/babel-parser/test/fixtures/typescript/catch-clause/invalid-type/input.ts b/packages/babel-parser/test/fixtures/typescript/catch-clause/invalid-type/input.ts new file mode 100644 index 000000000000..8885a7ce001c --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/catch-clause/invalid-type/input.ts @@ -0,0 +1 @@ +try {} catch (ex: string) {} diff --git a/packages/babel-parser/test/fixtures/typescript/catch-clause/invalid-type/output.json b/packages/babel-parser/test/fixtures/typescript/catch-clause/invalid-type/output.json new file mode 100644 index 000000000000..62ffaec37ef2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/catch-clause/invalid-type/output.json @@ -0,0 +1,42 @@ +{ + "type": "File", + "start":0,"end":28,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":28}}, + "errors": [ + "SyntaxError: Catch clause variable type annotation must be 'any' or 'unknown' if specified. (1:18)" + ], + "program": { + "type": "Program", + "start":0,"end":28,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":28}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TryStatement", + "start":0,"end":28,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":28}}, + "block": { + "type": "BlockStatement", + "start":4,"end":6,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":6}}, + "body": [], + "directives": [] + }, + "handler": { + "type": "CatchClause", + "start":7,"end":28,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":28}}, + "param": { + "type": "Identifier", + "start":14,"end":16,"loc":{"start":{"line":1,"column":14},"end":{"line":1,"column":16},"identifierName":"ex"}, + "name": "ex" + }, + "body": { + "type": "BlockStatement", + "start":26,"end":28,"loc":{"start":{"line":1,"column":26},"end":{"line":1,"column":28}}, + "body": [], + "directives": [] + } + }, + "finalizer": null + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/catch-clause/unknown/input.ts b/packages/babel-parser/test/fixtures/typescript/catch-clause/unknown/input.ts new file mode 100644 index 000000000000..a64f98e4bcc5 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/catch-clause/unknown/input.ts @@ -0,0 +1,3 @@ +try {} catch (ex) {} +try {} catch (ex: unknown) {} +try {} catch (ex: any) {} diff --git a/packages/babel-parser/test/fixtures/typescript/catch-clause/unknown/output.json b/packages/babel-parser/test/fixtures/typescript/catch-clause/unknown/output.json new file mode 100644 index 000000000000..092fff74a5b7 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/catch-clause/unknown/output.json @@ -0,0 +1,105 @@ +{ + "type": "File", + "start":0,"end":76,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":25}}, + "program": { + "type": "Program", + "start":0,"end":76,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":25}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TryStatement", + "start":0,"end":20,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":20}}, + "block": { + "type": "BlockStatement", + "start":4,"end":6,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":6}}, + "body": [], + "directives": [] + }, + "handler": { + "type": "CatchClause", + "start":7,"end":20,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":20}}, + "param": { + "type": "Identifier", + "start":14,"end":16,"loc":{"start":{"line":1,"column":14},"end":{"line":1,"column":16},"identifierName":"ex"}, + "name": "ex" + }, + "body": { + "type": "BlockStatement", + "start":18,"end":20,"loc":{"start":{"line":1,"column":18},"end":{"line":1,"column":20}}, + "body": [], + "directives": [] + } + }, + "finalizer": null + }, + { + "type": "TryStatement", + "start":21,"end":50,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":29}}, + "block": { + "type": "BlockStatement", + "start":25,"end":27,"loc":{"start":{"line":2,"column":4},"end":{"line":2,"column":6}}, + "body": [], + "directives": [] + }, + "handler": { + "type": "CatchClause", + "start":28,"end":50,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":29}}, + "param": { + "type": { + "type": "TSTypeAnnotation", + "start":37,"end":46,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":25}}, + "typeAnnotation": { + "type": "TSUnknownKeyword", + "start":39,"end":46,"loc":{"start":{"line":2,"column":18},"end":{"line":2,"column":25}} + } + }, + "start":35,"end":37,"loc":{"start":{"line":2,"column":14},"end":{"line":2,"column":16},"identifierName":"ex"}, + "name": "ex" + }, + "body": { + "type": "BlockStatement", + "start":48,"end":50,"loc":{"start":{"line":2,"column":27},"end":{"line":2,"column":29}}, + "body": [], + "directives": [] + } + }, + "finalizer": null + }, + { + "type": "TryStatement", + "start":51,"end":76,"loc":{"start":{"line":3,"column":0},"end":{"line":3,"column":25}}, + "block": { + "type": "BlockStatement", + "start":55,"end":57,"loc":{"start":{"line":3,"column":4},"end":{"line":3,"column":6}}, + "body": [], + "directives": [] + }, + "handler": { + "type": "CatchClause", + "start":58,"end":76,"loc":{"start":{"line":3,"column":7},"end":{"line":3,"column":25}}, + "param": { + "type": { + "type": "TSTypeAnnotation", + "start":67,"end":72,"loc":{"start":{"line":3,"column":16},"end":{"line":3,"column":21}}, + "typeAnnotation": { + "type": "TSAnyKeyword", + "start":69,"end":72,"loc":{"start":{"line":3,"column":18},"end":{"line":3,"column":21}} + } + }, + "start":65,"end":67,"loc":{"start":{"line":3,"column":14},"end":{"line":3,"column":16},"identifierName":"ex"}, + "name": "ex" + }, + "body": { + "type": "BlockStatement", + "start":74,"end":76,"loc":{"start":{"line":3,"column":23},"end":{"line":3,"column":25}}, + "body": [], + "directives": [] + } + }, + "finalizer": null + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/scripts/parser-tests/typescript/allowlist.txt b/scripts/parser-tests/typescript/allowlist.txt index eac6245793ea..ad5eb837ec79 100644 --- a/scripts/parser-tests/typescript/allowlist.txt +++ b/scripts/parser-tests/typescript/allowlist.txt @@ -48,6 +48,8 @@ augmentedTypesFunction.ts augmentedTypesInterface.ts augmentedTypesVar.ts bigintIndex.ts +binderBinaryExpressionStress.ts +binderBinaryExpressionStressJs.ts cacheResolutions.ts cachedModuleResolution1.ts cachedModuleResolution2.ts @@ -64,6 +66,7 @@ classCannotExtendVar.ts classExpressionWithDecorator1.ts classExtendsAcrossFiles.ts classExtendsMultipleBaseClasses.ts +classIndexer5.ts classOverloadForFunction.ts collisionExportsRequireAndClass.ts commonSourceDir5.ts @@ -87,8 +90,10 @@ declarationEmitDestructuringOptionalBindingParametersInOverloads.ts declarationEmitDestructuringParameterProperties.ts declarationEmitDestructuringWithOptionalBindingParameters.ts declarationEmitExpandoPropertyPrivateName.ts +declarationEmitExportAssignedNamespaceNoTripleSlashTypesReference.ts declarationEmitExportAssignment.ts declarationEmitExportDeclaration.ts +declarationEmitForModuleImportingModuleAugmentationRetainsImport.ts declarationEmitForTypesWhichNeedImportTypes.ts declarationEmitInterfaceWithNonEntityNameExpressionHeritage.ts declarationEmitPrefersPathKindBasedOnBundling.ts @@ -98,6 +103,7 @@ declarationImportTypeAliasInferredAndEmittable.ts declarationMapsMultifile.ts declarationMapsOutFile.ts declarationsForInferredTypeFromOtherFile.ts +declarationsIndirectGeneratedAliasReference.ts declareModifierOnImport1.ts decoratorMetadataRestParameterWithImportedType.ts decoratorMetadataWithImportDeclarationNameCollision.ts @@ -195,6 +201,7 @@ exportSameNameFuncVar.ts exportSpecifierAndExportedMemberDeclaration.ts exportSpecifierAndLocalMemberDeclaration.ts exportStarFromEmptyModule.ts +exportStarNotElided.ts expressionsForbiddenInParameterInitializers.ts extendingClassFromAliasAndUsageInIndexer.ts extendsClauseAlreadySeen.ts @@ -209,6 +216,8 @@ functionExpressionInWithBlock.ts functionExpressionWithResolutionOfTypeNamedArguments01.ts gettersAndSettersErrors.ts giant.ts +globalThisDeclarationEmit.ts +globalThisDeclarationEmit2.ts implementClausePrecedingExtends.ts implementsClauseAlreadySeen.ts importAndVariableDeclarationConflict1.ts @@ -227,13 +236,24 @@ importHelpersNoHelpers.ts importHelpersNoModule.ts importHelpersOutFile.ts importHelpersSystem.ts +importNonExportedMember10.ts +importNonExportedMember11.ts +importNonExportedMember4.ts +importNonExportedMember5.ts +importNonExportedMember6.ts +importNonExportedMember7.ts +importNonExportedMember8.ts +importNonExportedMember9.ts importWithTrailingSlash.ts +importedEnumMemberMergedWithExportedAliasIsError.ts importedModuleClassNameClash.ts indexSignatureWithAccessibilityModifier.ts indexSignatureWithInitializer1.ts +indexSignatureWithTrailingComma.ts indexTypeCheck.ts indexWithoutParamType.ts indexerSignatureWithRestParam.ts +inferrenceInfiniteLoopWithSubtyping.ts initializedParameterBeforeNonoptionalNotOptional.ts interfaceMayNotBeExtendedWitACall.ts interfaceWithImplements1.ts @@ -242,12 +262,15 @@ isLiteral1.ts isLiteral2.ts isolatedModulesReExportType.ts jsEnumTagOnObjectFrozen.ts +jsExportMemberMergedWithModuleAugmentation.ts jsFileCompilationBindDuplicateIdentifier.ts jsFileCompilationDuplicateFunctionImplementation.ts jsFileCompilationDuplicateFunctionImplementationFileOrderReversed.ts jsFileCompilationExternalPackageError.ts +jsFileImportPreservedWhenUsed.ts jsNoImplicitAnyNoCascadingReferenceErrors.ts jsdocAccessEnumType.ts +jsdocPropertyTagInvalid.ts jsxAttributeWithoutExpressionReact.tsx jsxIntrinsicElementsExtendsRecord.tsx letAndVarRedeclaration.ts @@ -335,6 +358,8 @@ preserveUnusedImports.ts privacyCheckExternalModuleExportAssignmentOfGenericClass.ts privacyTopLevelAmbientExternalModuleImportWithExport.ts privacyTopLevelAmbientExternalModuleImportWithoutExport.ts +privateFieldAssignabilityFromUnknown.ts +privateNameWeakMapCollision.ts reExportGlobalDeclaration1.ts reExportUndefined1.ts reExportUndefined2.ts @@ -388,6 +413,7 @@ unusedImports3.ts unusedImports4.ts unusedImports5.ts unusedInvalidTypeArguments.ts +usedImportNotElidedInJs.ts varAndFunctionShareName.ts varArgConstructorMemberParameter.ts withStatement.ts diff --git a/scripts/parser-tests/typescript/error-codes.js b/scripts/parser-tests/typescript/error-codes.js index 2a2580dfb8a2..16ce4eb71c94 100644 --- a/scripts/parser-tests/typescript/error-codes.js +++ b/scripts/parser-tests/typescript/error-codes.js @@ -40,7 +40,7 @@ module.exports = [ "TS1163", // A 'yield' expression is only allowed in a generator body. "TS1184", // Modifiers cannot appear here. "TS1191", // An import declaration cannot have modifiers. - "TS1196", // Catch clause variable cannot have a type annotation. + "TS1196", // Catch clause variable type annotation must be 'any' or 'unknown' if specified. "TS1197", // Catch clause variable cannot have an initializer. "TS1200", // Line terminator not permitted before arrow. "TS1312", // '=' can only be used in an object literal property inside a destructuring assignment.